传送门:www.lydsy.com/JudgeOnline/problem.php?id=1251
练习一下可持久化Treap
Code:
//ID:zky #include<cstdio> #include<climits> #include<iostream> #include<algorithm> using namespace std; int rnd(){ static int KEY=12345678; return KEY+=KEY<<2|1; } int tot; struct node; node *root,*Null; struct node{ int val,size,key,lazy,rev,maxx,ind; node *c[2]; void split(int need,node *&p,node *&q); node(int _val,node *C){ val=_val;size=1; key=rnd();lazy=rev=maxx=0; c[0]=c[1]=C;ind=tot++; } void add(int d){ val+=d; lazy+=d; maxx+=d; } void Rev(){ if(this==Null)return; rev^=1; swap(c[0],c[1]); } node *rz(){ size=1; maxx=val; if(c[0]!=Null) size+=c[0]->size,maxx=max(maxx,c[0]->maxx); if(c[1]!=Null) size+=c[1]->size,maxx=max(maxx,c[1]->maxx); return this; } void pushdown(){ if(this==Null)return; if(lazy){ if(c[0]!=Null) c[0]->add(lazy); if(c[1]!=Null) c[1]->add(lazy); lazy=0; } if(rev){ if(c[0]!=Null) c[0]->Rev(); if(c[1]!=Null) c[1]->Rev(); rev^=1; } } }; node *merge(node *p,node *q){ if(p==Null)return q->rz(); if(q==Null)return p->rz(); p->pushdown();q->pushdown(); if(p->key<q->key){ p->c[1]=merge(p->c[1],q); return p->rz(); }else{ q->c[0]=merge(p,q->c[0]); return q->rz(); } }void deb(node *x){ printf("#%d size:%d val:%d lazy:%d maxx:%d\n",x->ind,x->size,x->val,x->lazy,x->maxx); if(x->c[0]!=Null) printf("L:"),deb(x->c[0]); if(x->c[1]!=Null) printf("R:"),deb(x->c[1]); } void node::split(int need,node *&p,node *&q){ if(this==Null){p=q=Null;return;} pushdown(); if(c[0]->size>=need){ c[0]->split(need,p,q); c[0]=Null; rz(); q=merge(q,this); }else{ c[1]->split(need-c[0]->size-1,p,q); c[1]=Null; rz(); p=merge(this,p); } } struct Treap{ Treap(){ Null=new node(0,0); Null->size=0; Null->c[0]=Null->c[1]=Null; Null->key=INT_MAX;Null->maxx=0; Null->val=Null->lazy=Null->rev=0; root=Null; } void rev(int l0,int r0){ node *p,*q,*r,*s; root->split(l0-1,p,q); q->split(r0-l0+1,r,s); r->Rev(); root=merge(p,merge(r,s)); } void add(int l0,int r0,int d){ node *p,*q,*r,*s; root->split(l0-1,p,q); q->split(r0-l0+1,r,s); r->add(d);r->pushdown(); root=merge(p,merge(r,s)); } int Max(int l0,int r0){ node *p,*q,*r,*s; root->split(l0-1,p,q); q->split(r0-l0+1,r,s); int ans=r->maxx; root=merge(p,merge(r,s)); return ans; } }T; int n,m; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) root=merge(root,new node(0,Null)); while(m--){ int opt,l,r,d; scanf("%d",&opt); if(opt==1){ scanf("%d%d%d",&l,&r,&d); T.add(l,r,d); }else if(opt==2){ scanf("%d%d",&l,&r); T.rev(l,r); }else{ scanf("%d%d",&l,&r); printf("%d\n",T.Max(l,r)); } } return 0; }