The line segment tree maintains four tags for two values. Pay attention to the order of marking.
#include<bits/stdc++.h>#define N (1<<18)#define M (l+r>>1)#define P (k<<1)#define S (k<<1|1)#define L l,M,P#define R M+1,r,S#define Z int l=1,int r=n,int k=1using namespace std;int n;typedef int ds[N];ds a,b,c,d,u,v;int read(){int x;scanf("%d",&x);return x;}void update(int k){u[k]=max(u[P],u[S]);v[k]=max(v[P],v[S]);}void build(Z){if(l==r)u[k]=v[k]=read();else{build(L);build(R);update(k);}a[k]=c[k]=INT_MIN;}void A(int x,int k){u[k]=a[k]=x;b[k]=0;c[k]=max(c[k],a[k]);v[k]=max(v[k],u[k]);}void B(int x,int k){if(a[k]!=INT_MIN)A(a[k]+x,k);else{u[k]+=x;b[k]+=x;d[k]=max(d[k],b[k]);v[k]=max(v[k],u[k]);}}void C(int x,int k){c[k]=max(c[k],x);v[k]=max(v[k],c[k]);}void D(int x,int k){if(a[k]!=INT_MIN)C(a[k]+x,k);else{d[k]=max(d[k],b[k]+x);v[k]=max(v[k],u[k]+x);}}void devolve(int k){if(c[k]!=INT_MIN){C(c[k],P);C(c[k],S);c[k]=INT_MIN;}if(d[k]){D(d[k],P);D(d[k],S);d[k]=0;}if(a[k]!=INT_MIN){A(a[k],P);A(a[k],S);a[k]=INT_MIN;}if(b[k]){B(b[k],P);B(b[k],S);b[k]=0;}}void F(int x,int s,int t,Z){if(s==l&&t==r)A(x,k);else{devolve(k);if(t<=M)F(x,s,t,L);else if(s>M)F(x,s,t,R);else{F(x,s,M,L);F(x,M+1,t,R);}update(k);}}void G(int x,int s,int t,Z){if(s==l&&t==r)B(x,k);else{devolve(k);if(t<=M)G(x,s,t,L);else if(s>M)G(x,s,t,R);else{G(x,s,M,L);G(x,M+1,t,R);}update(k);}}int H(int s,int t,Z){if(s==l&&t==r)return u[k];devolve(k);return t<=M?H(s,t,L):s>M?H(s,t,R):max(H(s,M,L),H(M+1,t,R));}int I(int s,int t,Z){if(s==l&&t==r)return v[k];devolve(k);return t<=M?I(s,t,L):s>M?I(s,t,R):max(I(s,M,L),I(M+1,t,R));}int main(){char c[2];int m,s,t;n=read();build();m=read();while(m--){scanf("%s%d%d",c,&s,&t);if(*c==‘C‘)F(read(),s,t);if(*c==‘P‘)G(read(),s,t);if(*c==‘Q‘)printf("%d\n",H(s,t));if(*c==‘A‘)printf("%d\n",I(s,t));}}
Bzoj3064: tyvj 1518 CPU monitoring line segment tree