470 字
2 分钟
CodeForces 2193C: C. Replace and Sum
Codeforces
2026-01-30

题目链接#

https://codeforces.com/problemset/problem/2193/C

题目大意#

给定两个长度为 nn 的数组 aabb,以及 qq 个区间查询。 你可以对数组 aa 执行任意次(包括 00 次)以下两种操作:

  1. 选择一个下标 ii (1i<n1 \le i < n),将 aia_i 替换为 ai+1a_{i+1}(即 aiai+1a_i \leftarrow a_{i+1},向左传递数值);
  2. 选择一个下标 ii (1in1 \le i \le n),将 aia_i 替换为 bib_i(即 aibia_i \leftarrow b_i,从 bb 数组获取数值)。

对于每个查询给定的区间 [l,r][l, r],需要在允许任意次操作的前提下,使区间和最大化:

sum=al+al+1++ar\text{sum} = a_l + a_{l+1} + \cdots + a_r

请输出每个查询对应的最大区间和。

注意:

  • 操作次数不限;
  • 每个查询相互独立(即回答下一个查询时,数组 aa 视为恢复初始状态);
  • 数据规模较大,需使用高效算法。

解题思路#

核心性质aia_i 的最大值只能从后面(下标 i+1\ge i+1)传递过来,绝不可能从前面(下标 i1\le i-1)获取。

具体步骤

  1. 倒序遍历:从 ana_n 开始向前考虑。
  2. 状态转移:对于位置 ii,其最大值来源于当前 aia_i、对应 bib_i 以及后一位 ai+1a_{i+1} 的最大值。 ai=max(ai, bi, ai+1)a_i = \max(a_i, \ b_i, \ a_{i+1})
  3. 更新数组:以此类推,得到更新后的 aa 数组(即通过若干次操作后能得到的最大值)。
  4. 前缀和查询:对新数组计算前缀和,即可快速响应区间查询。

代码实现#

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll a[N], b[N], sum[N];
int T, n, q, l, r;
void solve(){
memset(a, 0, sizeof a); //一定要清空, 否则在a[n]=max(a[n], max(a[n+1], b[n]))的时候可能会出错,使用上一次的a[n+1]
memset(sum, 0, sizeof sum);
scanf("%d%d", &n, &q);
for(int i=1;i<=n;i++) scanf("%lld", &a[i]);
for(int i=1;i<=n;i++) scanf("%lld", &b[i]);
for(int i=n;i>=1;i--) a[i]=max(a[i], max(a[i+1], b[i]));
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
while(q--){
scanf("%d%d", &l, &r);
printf("%lld ", sum[r]-sum[l-1]);
printf("\n");
}
}
int main(){
scanf("%d", &T);
while(T--) solve();
return 0;
}
CodeForces 2193C: C. Replace and Sum
https://shenyize.com/posts/codeforces/2193c/
作者
Shenyize
发布于
2026-01-30
许可协议
CC BY-NC-SA 4.0