[BZOJ1251]序列终结者
题目大意:
维护一个长度为$n(n\leq50000)$的序列,支持区间加、区间反转、区间最值。操作共$m(m\leq100000)$次。
思路:
Splay维护区间,注意操作完如果对上面的结点有贡献,就一定要把这个点转到上面。
1 #include<cstdio> 2 #include<cctype> 3 #include<climits> 4 #include<algorithm> 5 inline int getint() { 6 register char ch; 7 register bool neg=false; 8 while(!isdigit(ch=getchar())) if(ch=='-') neg=true; 9 register int x=ch^'0'; 10 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 11 return neg?-x:x; 12 } 13 const int N=50003; 14 class SplayTree { 15 private: 16 int val[N],par[N],size[N],ch[N][2],max[N],tag[N],root; 17 bool rev[N]; 18 void push_up(const int &p) { 19 size[p]=size[ch[p][0]]+size[ch[p][1]]+1; 20 max[p]=std::max(val[p],std::max(max[ch[p][0]],max[ch[p][1]])); 21 } 22 void push_down(const int &p) { 23 if(rev[p]) { 24 std::swap(ch[p][0],ch[p][1]); 25 rev[ch[p][0]]^=1; 26 rev[ch[p][1]]^=1; 27 rev[p]=0; 28 } 29 if(ch[p][0]) { 30 tag[ch[p][0]]+=tag[p]; 31 val[ch[p][0]]+=tag[p]; 32 max[ch[p][0]]+=tag[p]; 33 } 34 if(ch[p][1]) { 35 tag[ch[p][1]]+=tag[p]; 36 val[ch[p][1]]+=tag[p]; 37 max[ch[p][1]]+=tag[p]; 38 } 39 tag[p]=0; 40 } 41 void rotate(const int &x) { 42 const int y=par[x],z=par[y]; 43 push_down(y),push_down(x); 44 const int b=x==ch[y][0]; 45 ch[par[par[ch[y][!b]=ch[x][b]]=y]=x][b]=y; 46 par[ch[z][y==ch[z][1]]=x]=z; 47 push_up(y),push_up(x); 48 } 49 void splay(int x,const int &goal) { 50 for(register int y=par[x],z=par[y];y!=goal;rotate(x),z=par[y=par[x]]) { 51 if(z!=goal) rotate((x==ch[y][0])^(y==ch[z][0])?x:y); 52 } 53 if(!goal) root=x; 54 } 55 int find(int x) { 56 for(register int y=root;;y=ch[y][size[ch[y][0]]<x]) { 57 push_down(y); 58 if(par[y]&&y==ch[par[y]][1]) x-=size[ch[par[y]][0]]+1; 59 if(size[ch[y][0]]==x) return y; 60 } 61 } 62 public: 63 void build(const int &n) { 64 max[0]=INT_MIN; 65 for(register int i=1;i<=n+2;i++) par[ch[i-1][1]=i]=i-1; 66 size[n+2]=1; 67 splay(n+2,0); 68 } 69 void modify(const int &l,const int &r,const int &x) { 70 splay(find(l-1),0); 71 splay(find(r+1),root); 72 if(!ch[ch[root][1]][0]) return; 73 tag[ch[ch[root][1]][0]]=x; 74 val[ch[ch[root][1]][0]]+=x; 75 max[ch[ch[root][1]][0]]+=x; 76 splay(ch[ch[root][1]][0],0); 77 } 78 void reverse(const int &l,const int &r) { 79 splay(find(l-1),0); 80 splay(find(r+1),root); 81 if(!ch[ch[root][1]][0]) return; 82 rev[ch[ch[root][1]][0]]^=1; 83 } 84 int query(const int &l,const int &r) { 85 splay(find(l-1),0); 86 splay(find(r+1),root); 87 return max[ch[ch[root][1]][0]]; 88 } 89 }; 90 SplayTree t; 91 int main() { 92 t.build(getint()); 93 for(register int i=getint();i;i--) { 94 const int opt=getint(),l=getint(),r=getint(); 95 if(opt==1) t.modify(l,r,getint()); 96 if(opt==2) t.reverse(l,r); 97 if(opt==3) printf("%d\n",t.query(l,r)); 98 } 99 return 0; 100 }