题目大意:维护一个数列支持以下操作:
这个Splay有毒,抄模板请参照这里
Splay裸题
可啪(?)的题,细节真的很重要
parent指针好像乱七八糟的样子,但是没用上…
在maintain操作前要先pushdown把标记推下去(标记也修改自己,不推标记的话不能保证信息的正确性)
子段和也要用自己的权值去更新
这俩错误查一天…
#include <cstdio>
#include <algorithm>
#define INF 500000001
#define Max(a,b) (a>b?a:b)
using namespace std;
int n,m,a[500005];
struct Node{
Node *ch[2],*pa;
int v,s,lmax,rmax,sum,maxs,fix;
bool flip,change;
Node(int);
int cmp(int x){
if(x==ch[0]->s+1) return -1;
return x < ch[0]->s+1 ? 0 : 1;
}
void maintain();
void pushdown();
}*null,*root;
void Node :: maintain(){
ch[0]->pushdown(); ch[1]->pushdown();
s=ch[0]->s+ch[1]->s+1;
sum=ch[0]->sum+ch[1]->sum+v;
lmax=Max(ch[0]->lmax,ch[0]->sum+v); lmax=Max(lmax,ch[0]->sum+v+ch[1]->lmax);
rmax=Max(ch[1]->rmax,ch[1]->sum+v); rmax=Max(rmax,ch[1]->sum+v+ch[0]->rmax);
maxs=Max(ch[0]->maxs,ch[1]->maxs); maxs=Max(maxs,v);
maxs=Max(ch[0]->rmax+v,maxs); maxs=Max(ch[1]->lmax+v,maxs); maxs=Max(ch[0]->rmax+v+ch[1]->lmax,maxs);
return ;
}
void Node :: pushdown(){
if(this==null) return ;
if(change){
change=false;
ch[0]->change=ch[1]->change=true;
ch[0]->fix=ch[1]->fix=fix;
sum=s*fix;
v=fix;
if(fix>0)lmax=rmax=maxs=sum;
else lmax=rmax=maxs=fix;
}
if(flip){
flip=false;
swap(ch[0],ch[1]);
swap(lmax,rmax);
ch[0]->flip=!ch[0]->flip;
ch[1]->flip=!ch[1]->flip;
}
return ;
}
Node :: Node(int v=0):v(v){
pa=ch[0]=ch[1]=null; flip=change=false;
if(!null){
lmax=rmax=maxs=-INF;
sum=0;
s=0;
}
else maintain();
}
void init(Node*& o,int l,int r){
int mid=(l+r)>>1;
if(l>r){
o=null;
return ;
}
o=new Node(a[mid]);
init(o->ch[0],l,mid-1); init(o->ch[1],mid+1,r);
if(o->ch[0]!=null) o->ch[0]->pa=o;
if(o->ch[1]!=null) o->ch[1]->pa=o;
o->maintain();
return ;
}
void Rotate(Node*& o,int d){
Node* k=o->ch[d^1];
o->ch[d^1]=k->ch[d]; k->ch[d]->pa=o;
k->ch[d]=o; k->pa=o->pa; o->pa=k;
o->maintain(); k->maintain();
o=k;
return ;
}
void Splay(Node*& o,int k){
o->pushdown();
int d=o->cmp(k);
if(d==1) k-=o->ch[0]->s+1;
if(d!=-1){
Node* p=o->ch[d];
p->pushdown();
int d2=p->cmp(k);
if(d2==1) k-=p->ch[0]->s+1;
if(d2!=-1){
Splay(p->ch[d2],k);
if(d==d2) Rotate(o,d^1);
else Rotate(o->ch[d],d);
}
Rotate(o,d^1);
}
return ;
}
Node* Merge(Node* l,Node* r){
if(l==null) return r;
Splay(l,l->s);
l->ch[1]=r;
r->pa=l;
l->maintain();
return l;
}
void Split(Node* o,int k,Node*& l,Node*& r){
if(!k){
l=null;
r=o;
return ;
}
Splay(o,k);
l=o;
r=o->ch[1];
o->ch[1]=null;
l->maintain();
return ;
}
void Delete(Node*& o){
if(o->ch[0]!=null) Delete(o->ch[0]);
if(o->ch[1]!=null) Delete(o->ch[1]);
delete o;
o=null;
return ;
}
int main(){
freopen("a.in","r",stdin); freopen("a.out","w",stdout);
null=new Node();
null->ch[0]=null->ch[1]=null->pa=null;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
init(root,1,n);
while(m--){
char c[10];
scanf("%s",c);
if(c[0]=='I'){//Insert
int pos,tot;
scanf("%d%d",&pos,&tot);
for(int i=1;i<=tot;i++) scanf("%d",&a[i]);
Node *o,*l,*r;
init(o,1,tot);
Split(root,pos,l,r);
root=Merge(Merge(l,o),r);
}
else if(c[0]=='D'){//Delete
int pos,tot;
scanf("%d%d",&pos,&tot);
Node *mid,*l,*r,*o;
Split(root,pos-1,l,o);
Split(o,tot,mid,r);
Delete(mid);
root=Merge(l,r);
}
else if(c[0]=='R'){//Reverse
int pos,tot;
scanf("%d%d",&pos,&tot);
Node *mid,*l,*r,*o;
Split(root,pos-1,l,o);
Split(o,tot,mid,r);
mid->flip=true;
root=Merge(Merge(l,mid),r);
}
else if(c[0]=='G'){//GET-SUM
int pos,tot;
scanf("%d%d",&pos,&tot);
if(!tot){
printf("0\n");
continue;
}
Node *mid,*l,*r,*o;
Split(root,pos-1,l,o);
Split(o,tot,mid,r);
printf("%d\n",mid->sum);
root=Merge(Merge(l,mid),r);
}
else if(c[2]=='X'){//MAX-SUM
printf("%d\n",root->maxs);
}
else {//MAKE-SAME
int pos,tot,cach;
scanf("%d%d%d",&pos,&tot,&cach);
Node *mid,*l,*r,*o;
Split(root,pos-1,l,o);
Split(o,tot,mid,r);
mid->change=true;
mid->fix=cach;
root=Merge(Merge(l,mid),r);
}
}
return 0;
}