1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| #include<bits/stdc++.h> #define maxn 100005 #define ll long long #define put() putchar('\n') using namespace std; inline void read(int &x){ int f=1;x=0;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();} x*=f; } const int inf=1e10; int n,a[maxn],sum[maxn]; struct yyy{ int lazy,Max,Min,ans; yyy(int a=-inf,int b=inf,int c=0) {Max=a,Min=b;ans=c;} }f[maxn<<2]; inline void Pushup(int rt) { f[rt].Max=max(f[rt<<1].Max,f[rt<<1|1].Max); f[rt].Min=min(f[rt<<1].Min,f[rt<<1|1].Min); f[rt].ans=max(f[rt<<1].ans,max(f[rt<<1|1].ans,f[rt<<1|1].Max-f[rt<<1].Min)); } inline void Pushdown(int rt) { if (f[rt].lazy) { int k=f[rt].lazy; f[rt<<1].Max+=k;f[rt<<1].Min+=k;f[rt<<1].lazy+=k; f[rt<<1|1].Max+=k,f[rt<<1|1].Min+=k,f[rt<<1|1].lazy+=k; f[rt].lazy=0; } } inline void Build(int l,int r,int rt) { if (l==r) {f[rt].ans=0;f[rt].Max=f[rt].Min=sum[l];return ;} int mid=l+r>>1;Build(l,mid,rt<<1);Build(mid+1,r,rt<<1|1);Pushup(rt); } inline void Update(int l,int r,int rt,int head,int tail,int k) { if (head<=l&&r<=tail) return f[rt].lazy+=k,f[rt].Min+=k,f[rt].Max+=k,void(); Pushdown(rt); int mid=l+r>>1; if (head<=mid) Update(l,mid,rt<<1,head,tail,k); if (tail>mid) Update(mid+1,r,rt<<1|1,head,tail,k); Pushup(rt); } inline int Query1(int l,int r,int rt,int head,int tail){ if (head<=l&&r<=tail) return f[rt].Max; Pushdown(rt); int tmp1=-inf,tmp2=-inf,mid=l+r>>1; if (head<=mid) tmp1=Query1(l,mid,rt<<1,head,tail); if (tail>mid) tmp2=Query1(mid+1,r,rt<<1|1,head,tail); return max(tmp1,tmp2); } inline int Query2(int l,int r,int rt,int head,int tail) { if (head<=l&&r<=tail) return f[rt].Min; Pushdown(rt); int tmp1=inf,tmp2=inf,mid=l+r>>1; if (head<=mid) tmp1=Query2(l,mid,rt<<1,head,tail); if (tail>mid) tmp2=Query2(mid+1,r,rt<<1|1,head,tail); return min(tmp1,tmp2); } inline yyy Query3(int l,int r,int rt,int head,int tail) { if (head<=l&&r<=tail) return f[rt]; Pushdown(rt); int mid=l+r>>1; if (head<=mid&&tail>mid) { yyy tmp1=Query3(l,mid,rt<<1,head,tail),tmp2=Query3(mid+1,r,rt<<1|1,head,tail); return yyy(max(tmp1.Max,tmp2.Max),min(tmp1.Min,tmp2.Min),max(tmp1.ans,max(tmp2.ans,tmp2.Max-tmp1.Min))); } else if (head<=mid) return Query3(l,mid,rt<<1,head,tail); else if (tail>mid) return Query3(mid+1,r,rt<<1|1,head,tail); } signed main(void){ freopen("sum.in","r",stdin); freopen("sum.out","w",stdout); int n,T,i,x,y,l1,l2,r1,r2;char ch; read(n);read(T); for (i=1;i<=n;i++) read(a[i]),sum[i]+=sum[i-1]+a[i]; Build(0,n,1); while (T--) { ch=getchar();while (ch!='C'&&ch!='Q') ch=getchar(); if (ch=='C') read(x),read(y),Update(0,n,1,x,n,y-a[x]),a[x]=y; else { read(l1);read(r1);read(l2);read(r2); if (l1>r1) swap(l1,r1); if (l2>r2) swap(l2,r2); if (l1>l2) swap(l1,l2),swap(r1,r2); if (r1<=l2) printf("%d\n",Query1(0,n,1,l2,r2)-Query2(0,n,1,l1-1,r1-1)); else { int ans=0; if (r2<r1) { ans=max(Query1(0,n,1,l2,r2)-Query2(0,n,1,l1-1,l2-1),ans); ans=max(Query3(0,n,1,l2-1,r2).ans,ans); } else { ans=max(Query1(0,n,1,l2,r2)-Query2(0,n,1,l1-1,l2-1),ans); ans=max(Query1(0,n,1,r1,r2)-Query2(0,n,1,l1-1,r1-1),ans); ans=max(Query3(0,n,1,l2-1,r1).ans,ans); } printf("%d\n",ans); } } } return 0; }
|