恶心的线段树
维护6个标记
最后调不出来找来标程
原来标记的先后顺序也有关系
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> using namespace std; const int N=100005,INF=2100000000; int T,E,a[N]; struct SegTree{ int add,mx,cov,l,r; }tree[4*N],histree[4*N]; void CheckMax(int rt,int val){histree[rt].mx=max(histree[rt].mx,val);} void HisAdd(int rt,int val){ CheckMax(rt,tree[rt].mx+val); if(tree[rt].cov>-INF)histree[rt].cov=max(histree[rt].cov,tree[rt].cov+val); else histree[rt].add=max(histree[rt].add,tree[rt].add+val); } void HisCover(int rt,int val){ CheckMax(rt,val); histree[rt].cov=max(histree[rt].cov,val); } void Add(int rt,int val){ CheckMax(rt,tree[rt].mx+=val); if(tree[rt].cov>-INF)histree[rt].cov=max(histree[rt].cov,tree[rt].cov+=val); else histree[rt].add=max(histree[rt].add,tree[rt].add+=val); } void Cover(int rt,int val){ CheckMax(rt,tree[rt].mx=val); histree[rt].cov=max(histree[rt].cov,tree[rt].cov=val); tree[rt].add=0; } void Pushdown(int rt){ if(histree[rt].add){ HisAdd(rt<<1,histree[rt].add); HisAdd(rt<<1|1,histree[rt].add); histree[rt].add=0; } if(histree[rt].cov!=-INF){ HisCover(rt<<1,histree[rt].cov); HisCover(rt<<1|1,histree[rt].cov); histree[rt].cov=-INF; } if(tree[rt].add){ Add(rt<<1,tree[rt].add); Add(rt<<1|1,tree[rt].add); tree[rt].add=0; } if(tree[rt].cov!=-INF){ Cover(rt<<1,tree[rt].cov); Cover(rt<<1|1,tree[rt].cov); tree[rt].cov=-INF; } } void Pushup(int rt){ histree[rt].mx=max(histree[rt].mx,max(histree[rt<<1].mx,histree[rt<<1|1].mx)); tree[rt].mx=max(tree[rt<<1].mx,tree[rt<<1|1].mx); } void Build(int rt,int l,int r){ tree[rt].l=l; tree[rt].r=r; tree[rt].add=0; tree[rt].mx=-INF; tree[rt].cov=-INF; histree[rt].l=l; histree[rt].r=r; histree[rt].add=0; histree[rt].mx=-INF; histree[rt].cov=-INF; if(l==r){tree[rt].mx=histree[rt].mx=a[l];return;} int mid=l+r>>1; Build(rt<<1,l,mid); Build(rt<<1|1,mid+1,r); Pushup(rt); } void Plus(int rt,int l,int r,int val){ if(l<=tree[rt].l && tree[rt].r<=r){ Add(rt,val); return; } Pushdown(rt); int mid=tree[rt].l+tree[rt].r>>1; if(l<=mid)Plus(rt<<1,l,r,val); if(r>mid)Plus(rt<<1|1,l,r,val); Pushup(rt); } void Change(int rt,int l,int r,int val){ if(l<=tree[rt].l && tree[rt].r<=r){ Cover(rt,val); return; } Pushdown(rt); int mid=tree[rt].l+tree[rt].r>>1; if(l<=mid)Change(rt<<1,l,r,val); if(r>mid)Change(rt<<1|1,l,r,val); Pushup(rt); } int Query(int rt,int l,int r){ if(l<=tree[rt].l && tree[rt].r<=r)return tree[rt].mx; Pushdown(rt); int mid=tree[rt].l+tree[rt].r>>1,ans=-INF; if(l<=mid)ans=max(ans,Query(rt<<1,l,r)); if(r>mid)ans=max(ans,Query(rt<<1|1,l,r)); return ans; } int Ask(int rt,int l,int r){ if(l<=histree[rt].l && histree[rt].r<=r)return histree[rt].mx; Pushdown(rt); int mid=histree[rt].l+histree[rt].r>>1,ans=-INF; if(l<=mid)ans=max(ans,Ask(rt<<1,l,r)); if(r>mid)ans=max(ans,Ask(rt<<1|1,l,r)); return ans; } int main(){ freopen("3064.in","r",stdin); freopen("3064.out","w",stdout); scanf("%d",&T); for(int i=1;i<=T;i++)scanf("%d",&a[i]); Build(1,1,T); scanf("%d",&E); for(int i=1;i<=E;i++){ char s[10]; int x,y,z; scanf("%s",s); if(s[0]=='Q'){scanf("%d %d",&x,&y);printf("%d\n",Query(1,x,y));} if(s[0]=='A'){scanf("%d %d",&x,&y);printf("%d\n",Ask(1,x,y));} if(s[0]=='P'){scanf("%d %d %d",&x,&y,&z);Plus(1,x,y,z);} if(s[0]=='C'){scanf("%d %d %d",&x,&y,&z);Change(1,x,y,z);} } return 0; }