我们统计一波区间的最大最小值。
answer=max(sum-区间最小值,区间最大值);
特判一点,当最小值>0时,那么我们把最小值减去,因为我们不能选一个圈。
一遍过样例什么的最虚了。
#include<cstdio> #include<iostream> #include<algorithm> #define sight(x) (‘0‘<=x&&x<=‘9‘) #define N 100007 #define TN (N<<2)|N using namespace std; inline void read(int &x){ static int b;static char c; for (c=getchar(),b=1;!sight(c);c=getchar())if (c==‘-‘) b=-1; for (x=0;sight(c);c=getchar()) x=x*10+c-48;x*=b; } int x,y,q,n,a[N],Sum,mm[TN],ma[TN],mi[TN],sum[TN],lmax[TN],rmax[TN],lmin[TN],rmin[TN]; #define Mid (l+r>>1) inline void up(int No){ mm[No]=min(mm[No<<1],mm[No<<1|1]); ma[No]=max(ma[No<<1],ma[No<<1|1]); mi[No]=min(mi[No<<1],mi[No<<1|1]); ma[No]=max(ma[No],rmax[No<<1]+lmax[No<<1|1]); mi[No]=min(mi[No],rmin[No<<1]+lmin[No<<1|1]); sum[No]=sum[No<<1]+sum[No<<1|1]; lmax[No]=max(lmax[No<<1],sum[No<<1]+lmax[No<<1|1]); rmax[No]=max(rmax[No<<1|1],sum[No<<1|1]+rmax[No<<1]); lmin[No]=min(lmin[No<<1],sum[No<<1]+lmin[No<<1|1]); rmin[No]=min(rmin[No<<1|1],sum[No<<1|1]+rmin[No<<1]); } void build (int No,int l,int r){ if (l==r) { ma[No]=rmax[No]=lmax[No]=a[l]; mi[No]=rmin[No]=lmin[No]=a[l]; sum[No]=mm[No]=a[l]; return; } build(No<<1,l,Mid); build(No<<1|1,Mid+1,r); up(No); } void change(int No,int l,int r,int x){ if (l==r) { ma[No]=rmax[No]=lmax[No]=a[l]; mi[No]=rmin[No]=lmin[No]=a[l]; sum[No]=mm[No]=a[l]; return; } if (x<=Mid) change(No<<1,l,Mid,x); else change(No<<1|1,Mid+1,r,x); up(No); } inline void out() { if (mm[1]>0) { printf("%d\n",Sum-mm[1]);return;} printf("%d\n",max(Sum-mi[1],ma[1])); } int main () { read(n); for (int i=1;i<=n;i++) {read(a[i]); Sum+=a[i];} build(1,1,n); read(q); while (q--) { read(x);read(y); Sum-=a[x]; Sum+=y; a[x]=y; change(1,1,n,x); out(); } }