题目:http://codeforces.com/contest/182/problem/C
题意:让你求一个长度为len的区间的和的绝对值。但是你可以对数组中的数进行k次操作,每次可以将ai变为-ai。问最大的绝对值为多少。
可以用multiset来维护区间内最大的k个负数,同时维护s
然后将ai全部取反后再维护一遍
最后就可以得到最大值
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+5; int a[N]; int main() { int n,len; scanf("%d%d",&n,&len); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int k; scanf("%d",&k); ll ans=-1e18; for(int sign=0;sign<=1;sign++) { if (sign==1) for(int i=1;i<=n;i++) a[i]=-a[i]; ll s=0; multiset<int> x,y; for(int i=1;i<=n;i++) { if (a[i]>=0) s+=a[i]; else if (x.size()<k) { x.insert(a[i]); s+=-a[i]; } else if (k!=0&&a[i]<*(--x.end())) { x.insert(a[i]); s+=-a[i]; int v=*(--x.end()); x.erase(x.find(v)); y.insert(v); s-=-v;s+=v; } else { y.insert(a[i]); s+=a[i]; } int j=i-len; if (j>=1) { if (a[j]>=0) s-=a[j]; else if (x.find(a[j])!=x.end()) { x.erase(x.find(a[j])); s-=-a[j]; if (!y.empty()) { int v=*(y.begin()); x.insert(v); y.erase(y.find(v)); s-=v;s+=-v; } } else { y.erase(y.find(a[j])); s-=a[j]; } } if (j>=0) ans=max(ans,s); } } printf("%I64d ",ans); return 0; }