专栏文章
题解:CF182C Optimal Sum
CF182C题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miozt104
- 此快照首次捕获于
- 2025/12/03 03:50 3 个月前
- 此快照最后确认于
- 2025/12/03 03:50 3 个月前
题目传送门
题目大意
有一个长度为 的数列 ,可以对它进行最多 次操作,每次操作可以将一个数变为它的相反数,输出最后所有长度为 的数列的和的绝对值的最大值。
思路
根据贪心,我们发现对于一个长度为 的数列,要么把它的前 大正数变为相反数,要么把它的前 小负数变为相反数,这样保证最优。所以我们可以用 个
multiset 分别维护当前在 区间内的前 大正数,区间内的其余正数,区间内的前 小负数,区间内的其余负数。每次往后移动一位时,判断这一位数的正负,假定为正,那么把他与第一个
multiset 中的最小值比较,如果比它大,那么就把他加入第一个 multiset,否则加入第二个 multiset。否则,加入第二个。删除同理,如果这个数原本在第一个
multiset 中,那么就把第二个 multiset 中的最大值加入第一个 multiset,否则直接从第二个 multiset 中删除即可。注意删除前,一定要判断这个数是否在
multiset 中。代码
CPP#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1010101;
ll n,len,k,a[N],sum1,sum2,sum,ans;
multiset<ll>st1,st2,st3,st4;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>len;
for(int i=1;i<=n;i++)cin>>a[i];
cin>>k;
for(int i=1;i<=n;i++){
sum=sum+a[i]-a[max(i-len,0ll)];
if(k==0){
if(i>=len)ans=max(ans,abs(sum));
continue;
}
if(a[i]>=0){
if(st1.size()<k)st1.insert(-a[i]),sum1+=a[i];
else{
if(-a[i]<=*st1.rbegin()){
sum1+=a[i];
sum1+=*st1.rbegin();
st3.insert(*st1.rbegin());
st1.erase(--st1.end());
st1.insert(-a[i]);
}
else st3.insert(-a[i]);
}
}
if(a[i]<0){
if(st2.size()<k)st2.insert(a[i]),sum2+=a[i];
else{
if(a[i]<=*st2.rbegin()){
sum2+=a[i];
sum2-=*st2.rbegin();
st4.insert(*st2.rbegin());
st2.erase(--st2.end());
st2.insert(a[i]);
}
else st4.insert(a[i]);
}
}
if(a[max(i-len,0ll)]>=0&&i>len){
if(st1.find(-a[i-len])!=st1.end()){
st1.erase(st1.find(-a[i-len]));
st1.insert(*st3.begin());
sum1-=a[i-len];
sum1-=*st3.begin();
if(st3.begin()!=st3.end())st3.erase(st3.begin());
}
else if(st3.find(-a[i-len])!=st3.end())st3.erase(st3.find(-a[i-len]));
}
if(a[max(i-len,0ll)]<0&&i>len){
if(st2.find(a[i-len])!=st2.end()){
st2.erase(st2.find(a[i-len]));
st2.insert(*st4.begin());
sum2-=a[i-len];
sum2+=*st4.begin();
if(st4.begin()!=st4.end())st4.erase(st4.begin());
}
else if(st4.find(a[i-len])!=st4.end())st4.erase(st4.find(a[i-len]));
}
if(i>=len)ans=max(ans,max(abs(sum-2*sum1),abs(sum-2*sum2)));
}
cout<<ans;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...