P9742 题解(2023 激励计划评分 9)
P9742 题解
题目大意
给定一个数列
题目思路
- 当
c_i>0 时,我们肯定希望i 的排名上升。 - 当
c_i<0 时,我们肯定希望i 的排名下降。 - 当
c_i=0 时,则排名任意。
先讨论
显然可以让第一名掉到最后一名,其他人顺次往前移一位。但这可能不是最优方案。
但是我们可以让
那么
现在考虑正解。
我们可以将原数列分成三部分:
第一部分:
第二部分:
第三部分:
对于第一、二部分,我们可以直接套用上面的结论。
对于第三部分,
参考代码
有一个细节,就是用前缀和优化,见代码:
#include<bits/stdc++.h>
#define gsum(l,r) (sum[r]-sum[l-1])
using namespace std;
typedef long long ll;
const int N=2e5+5;
ll T,n,c[N],tmp,lft,rgt,sum[N],ans1,ans2;
int main(){
cin>>T;
while(T--){
ans1=ans2=0;
cin>>n;
for(int i=1;i<=n;i++) scanf("%lld",&tmp);
for(int i=1;i<=n;i++){
scanf("%lld",c+i);
sum[i]=sum[i-1]+abs(c[i]);
}
for(lft=1;c[lft]>0&&lft<=n;lft++);
for(rgt=n;c[rgt]<0&&rgt>=1;rgt--);
for(int i=1;i<lft;i++) ans1=max(ans1,-c[i]+gsum(i+1,lft-1));
for(int i=n;i>rgt;i--) ans2=max(ans2,c[i]+gsum(rgt+1,i-1));
cout<<ans1+ans2+gsum(lft,rgt)<<'\n';
}
return 0;
}