传送门: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;
}