欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ3064
题意概括
一个序列,要你支持以下操作:
1. 区间询问最大值
2. 区间询问历史最大值
3. 区间加某一个值
4. 区间赋值
序列长度<=100000, 操作数<=100000
题解
http://blog.csdn.net/vmurder/article/details/43271091
为了一个傻逼错误找了2个小时的我,实在不想写题解了。请您看上面那个链接 的……
代码
#include <cstring> #include <algorithm> #include <cstdio> #include <cmath> #include <cstdlib> using namespace std; typedef long long LL; const int N=100005; const int Inf=2147483647; struct Tree{ int hMax,Max,hadd,add,hco,co; }t[N*4]; int n,m,v[N]; void p(int &a,int b){ a=max(a,b); } void pushup(int rt){ int ls=rt<<1,rs=ls|1; t[rt].Max=max(t[ls].Max,t[rs].Max); p(t[rt].hMax,max(t[ls].hMax,t[rs].hMax)); } void build(int rt,int L,int R){ t[rt].add=t[rt].hadd=0,t[rt].hco=t[rt].co=-Inf; if (L==R){ t[rt].Max=t[rt].hMax=v[L]; return; } int mid=(L+R)>>1,ls=rt<<1,rs=ls|1; build(ls,L,mid); build(rs,mid+1,R); pushup(rt); } void now_add(int rt,int v){ if (t[rt].co>-Inf) p(t[rt].hco,t[rt].co+=v); else p(t[rt].hadd,t[rt].add+=v); p(t[rt].hMax,t[rt].Max+=v); } void now_cover(int rt,int v){ p(t[rt].hMax,t[rt].Max=v); p(t[rt].hco,t[rt].co=v); t[rt].add=0; } void his_add(int rt,int v){ p(t[rt].hMax,t[rt].Max+v); if (t[rt].co>-Inf) p(t[rt].hco,t[rt].co+v); else p(t[rt].hadd,t[rt].add+v); } void his_cover(int rt,int v){ p(t[rt].hMax,v); p(t[rt].hco,v); } void pushdown(int rt){ int ls=rt<<1,rs=ls|1; int &add=t[rt].add,&hadd=t[rt].hadd,&co=t[rt].co,&hco=t[rt].hco; if (hadd){ his_add(ls,hadd); his_add(rs,hadd); hadd=0; } if (hco>-Inf){ his_cover(ls,hco); his_cover(rs,hco); hco=-Inf; } if (add){ now_add(ls,add); now_add(rs,add); add=0; } if (co>-Inf){ now_cover(ls,co); now_cover(rs,co); co=-Inf; } } void update(int rt,int le,int ri,int xle,int xri,int v,int op){ if (le>xri||ri<xle) return; if (xle<=le&&ri<=xri){ if (!op) now_add(rt,v); else now_cover(rt,v); return; } pushdown(rt); int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1; update(ls,le,mid,xle,xri,v,op); update(rs,mid+1,ri,xle,xri,v,op); pushup(rt); } int query(int rt,int le,int ri,int xle,int xri,int op){ if (le>xri||ri<xle) return -Inf; if (xle<=le&&ri<=xri) return op?t[rt].hMax:t[rt].Max; pushdown(rt); int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1; return max(query(ls,le,mid,xle,xri,op),query(rs,mid+1,ri,xle,xri,op)); } int main(){ scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&v[i]); build(1,1,n); scanf("%d",&m); for (int i=1;i<=m;i++){ char op[5]; int x,y,z; scanf("%s",op); if (op[0]=='Q'){ scanf("%d%d",&x,&y); printf("%d ",query(1,1,n,x,y,0)); } if (op[0]=='A'){ scanf("%d%d",&x,&y); printf("%d ",query(1,1,n,x,y,1)); } if (op[0]=='P'){ scanf("%d%d%d",&x,&y,&z); update(1,1,n,x,y,z,0); } if (op[0]=='C'){ scanf("%d%d%d",&x,&y,&z); update(1,1,n,x,y,z,1); } } return 0; }