0%

Edu-CF-184-C. Range Operation(仅有一次的,进行奇奇怪怪操作的,均可以用 dp 解决)(式子中有 r,l,一定要想办法分离)

题目大意

CF2169C Range Operation

题目描述

给定一个长度为 nn 的整数数组 aa

你可以进行以下操作:选择一个区间 [l,r][l, r]1lrn1 \le l \le r \le n),并将区间内的元素 al,al+1,,ara_l, a_{l+1}, \dots, a_r 全部替换为 l+rl + r

你的任务是计算,在最多允许进行一次上述操作的情况下,数组的和可能达到的最大值。

输入格式

第一行包含一个整数 tt1t1041 \le t \le 10^4),表示测试用例的数量。

每个测试用例的第一行包含一个整数 nn1n21051 \le n \le 2 \cdot 10^5)。

第二行包含 nn 个整数 a1,a2,,ana_1, a_2, \dots, a_n0ai2n0 \le a_i \le 2n)。

输入额外限制:所有测试用例中 nn 的总和不超过 21052 \cdot 10^5

输出格式

对于每个测试用例,输出一个整数,表示在至多进行一次操作后数组的最大和。

输入输出样例 #1

输入 #1

1
2
3
4
5
6
7
8
9
10
4
3
2 5 1
2
4 4
4
1 3 2 1
5
3 2 0 9 10

输出 #1

1
2
3
4
5
13
8
20
32

说明/提示

在第一个样例中,可以对子数组 [3,3][3,3] 执行操作,得到数组 [2,5,6][2, 5, 6],其和为 1313

在第二个样例中,不需进行任何操作。

在第三个样例中,可以对子数组 [1,4][1,4] 执行操作,得到数组 [5,5,5,5][5, 5, 5, 5],其和为 2020

在第四个样例中,可以对子数组 [2,3][2,3] 执行操作,得到数组 [3,5,5,9,10][3, 5, 5, 9, 10],其和为 3232

由 ChatGPT 5 翻译

思路讲解

类似于求解最大字段和的 dp。

思路参考了 starsilk 的代码。

首先,我们必须要把 r,lr,l 两者分开。

image

我们就会发现,总答案就可以写为:(SxS_{x} 表示 xx 的前缀和)

ans=Sl1+l(1l)+SnSr+r(r+1)ans=S_{l-1}+l(1-l)+S_n-S_{r}+r(r+1)

这个明显可以使用这个 dp,因为我们只需要最优化 Sl1+l(1l)S_{l-1}+l(1-l) 这个值,就直接最优化了左端点。而右端点的转移,一旦不用考虑这个左端点是不是最优的,就容易多了。

那我们定义,dpi,0dp_{i,0} 为前缀和(操作前),dpi,1dp_{i,1} 表示从 ii 及之前开始转化的最大化 Sl1+l(1l)S_{l-1}+l(1-l) 值(可以理解为操作中,但是不严谨),dpi,2dp_{i,2} 表示 ii 以及之前转化结束,所能达到的最大和(操作后)。

之所以定义三个状态,而不是两个,是为了避免重复操作。

dpi,0=dpi1,0+aidpi,1=max(dpi1,1,dpi1,0+i(1i))dpi,2=max(dpi1,2+ai,dpi,1+i(i+1))dp_{i,0}=dp_{i-1,0}+a_i\\ dp_{i,1}=\max(dp_{i-1,1},dp_{i-1,0}+i(1-i))\\ dp_{i,2}=\max(dp_{i-1,2}+a_i,dp_{i,1}+i(i+1))

这个状态转移式子中 dpi,2dp_{i,2} 之所以有两个来源,就是其状态定义,在 ii 之前转化结束一个来源,在 ii 结束一个来源。

ii 定义为这个长整型,小心溢出

1
2
3
4
5
6
7
8
9
// dp[i][0] 就是前缀和,dp[i][1]是这个预备变量
for (ll i=1;i<=N;++i) {
dp[i][0]=dp[i-1][0]+A[i];
// dp[i][1] 代表从 i 开始变换,我们能得到的最大值(左端)
// 即 S[i-1]+i*(1-i) 的最大值
dp[i][1]=max(dp[i-1][1],dp[i-1][0]+i*(1-i));
dp[i][2]=max(dp[i-1][2]+A[i],dp[i][1]+i*(i+1));
}
cout<<max(dp[N][0],dp[N][2])<<"\n";

AC代码

AC
https://codeforces.com/contest/2169/submission/360407408

心路历程(WA,TLE,MLE……)