Splay 练手题(本来块链能过我非要作死用Splay结果调成狗OLZ
写的又慢又长简直不能看OLZ
AC code:
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF=1<<29;
int n,m,cnt;
struct nod{
int v,tot,sum,lm,mm,rm,c;
bool tc,tr;
nod *ch[2],*pr;
}*NIL;
struct Splay{
nod *root;
Splay(){
root=NIL=new nod;
NIL->sum=NIL->tot=0;
NIL->lm=NIL->mm=NIL->rm=-INF;
}
void clear(nod *p){
if(p==NIL) return ;
if(p->tc){
p->v=p->c;p->sum=p->tot*p->c;
if(p->c<0) p->lm=p->mm=p->rm=p->c;
else p->lm=p->mm=p->rm=p->sum;
p->ch[0]->c=p->ch[1]->c=p->c;
p->ch[0]->tc=p->ch[1]->tc=1;
p->tc=0;
}
if(p->tr){
int x=p->lm;p->lm=p->rm;p->rm=x;
nod *y=p->ch[0];p->ch[0]=p->ch[1];p->ch[1]=y;
p->tr=0;p->ch[0]->tr^=1;p->ch[1]->tr^=1;
}
}
void update(nod *p){
clear(p->ch[0]);clear(p->ch[1]);
p->tot=p->ch[0]->tot+p->ch[1]->tot+1;
p->sum=p->ch[0]->sum+p->ch[1]->sum+p->v;
p->lm=max(p->ch[0]->lm,p->ch[0]->sum+p->v+max(0,p->ch[1]->lm));
p->mm=max(p->ch[0]->mm,max(p->ch[1]->mm,max(0,p->ch[0]->rm)+p->v+max(0,p->ch[1]->lm)));
p->rm=max(p->ch[1]->rm,max(0,p->ch[0]->rm)+p->v+p->ch[1]->sum);
}
void rotate(nod *x,bool t){
nod *y=x->pr,*z=y->pr,*b=x->ch[t^1];
b->pr=y;y->pr=x;x->pr=z;y->ch[t]=b;x->ch[t^1]=y;
if(z->ch[0]==y) z->ch[0]=x;
else if(z->ch[1]==y) z->ch[1]=x;
update(y);update(x);
}
void splay(nod *x,nod *obj){
while(x->pr!=obj){
nod *y=x->pr,*z=y->pr;
if(z==obj&&y->ch[0]==x) rotate(x,0);
else if(z==obj&&y->ch[1]==x) rotate(x,1);
else if(z->ch[0]==y&&y->ch[0]==x){rotate(y,0);rotate(x,0);}
else if(z->ch[1]==y&&y->ch[1]==x){rotate(y,1);rotate(x,1);}
else if(z->ch[1]==y){rotate(x,0);rotate(x,1);}
else{rotate(x,1);rotate(x,0);}
}
if(obj==NIL) root=x;
}
nod* get(int k){
nod *p=root;
clear(p);
while(p->ch[0]->tot+1!=k){
if(p->ch[0]->tot+1>k) p=p->ch[0];
else{k-=p->ch[0]->tot+1;p=p->ch[1];}
clear(p);
}
return p;
}
void newnod(nod *pre,nod **p,int t){
*p=new nod;
(*p)->v=(*p)->sum=(*p)->lm=(*p)->mm=(*p)->rm=t;(*p)->tot=1;(*p)->tc=(*p)->tr=0;
(*p)->ch[0]=(*p)->ch[1]=NIL;(*p)->pr=pre;
}
void insert(int pos,int t){
if(!pos){
if(root==NIL) newnod(NIL,&root,t);
else{
splay(get(1),NIL);
newnod(root,&root->ch[0],t);
splay(root->ch[0],NIL);
}
}
else if(pos==root->tot){
splay(get(root->tot),NIL);
newnod(root,&root->ch[1],t);
splay(root->ch[1],NIL);
}
else{
splay(get(pos),NIL);
splay(get(pos+1),root);
newnod(root->ch[1],&root->ch[1]->ch[0],t);
splay(root->ch[1]->ch[0],NIL);
}
}
void del(nod *p){
queue<nod*> Q;
Q.push(p);
while(!Q.empty()){
nod *q=Q.front();Q.pop();
if(q->ch[0]!=NIL) Q.push(q->ch[0]);
if(q->ch[1]!=NIL) Q.push(q->ch[1]);
delete q;
}
}
void erase(int L,int R){
if(L==1&&R==root->tot) del(root);
else if(L==1){
splay(get(R+1),NIL);
del(root->ch[0]);
root->ch[0]=NIL;
update(root);
}
else if(R==root->tot){
splay(get(L-1),NIL);
del(root->ch[1]);
root->ch[1]=NIL;
update(root);
}
else{
splay(get(L-1),NIL);
splay(get(R+1),root);
del(root->ch[1]->ch[0]);
root->ch[1]->ch[0]=NIL;
update(root->ch[1]);update(root);
}
}
void change(int L,int R,int t){
if(L==1&&R==root->tot){root->tc=1;root->c=t;}
else if(L==1){
splay(get(R+1),NIL);
root->ch[0]->tc=1;root->ch[0]->c=t;
clear(root->ch[0]);update(root);
}
else if(R==root->tot){
splay(get(L-1),NIL);
root->ch[1]->tc=1;root->ch[1]->c=t;
clear(root->ch[1]);update(root);
}
else{
splay(get(L-1),NIL);
splay(get(R+1),root);
root->ch[1]->ch[0]->tc=1;root->ch[1]->ch[0]->c=t;
clear(root->ch[1]->ch[0]);update(root->ch[1]);update(root);
}
}
void reverse(int L,int R){
if(L==1&&R==root->tot){root->tr^=1;}
else if(L==1){
splay(get(R+1),NIL);
root->ch[0]->tr^=1;
clear(root->ch[0]);update(root);
}
else if(R==root->tot){
splay(get(L-1),NIL);
root->ch[1]->tr^=1;
clear(root->ch[1]);update(root);
}
else{
splay(get(L-1),NIL);
splay(get(R+1),root);
root->ch[1]->ch[0]->tr^=1;
clear(root->ch[1]->ch[0]);update(root->ch[1]);update(root);
}
}
void getsum(int L,int R){
if(L==1&&R==root->tot){
clear(root);
printf("%d\n",root->sum);
}
else if(L==1){
splay(get(R+1),NIL);
clear(root->ch[0]);
printf("%d\n",root->ch[0]->sum);
}
else if(R==root->tot){
splay(get(L-1),NIL);
clear(root->ch[1]);
printf("%d\n",root->ch[1]->sum);
}
else{
splay(get(L-1),NIL);
splay(get(R+1),root);
clear(root->ch[1]->ch[0]);
printf("%d\n",root->ch[1]->ch[0]->sum);
}
}
void maxsum(){
clear(root);
printf("%d\n",root->mm);
}
};
int main(){
Splay T;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
int t;
scanf("%d",&t);
T.insert(i-1,t);
}
for(int i=1;i<=m;i++){
int pos,tot;
char ord[11];
scanf("%s%d%d",ord,&pos,&tot);
if(ord[0]=='I'){
for(int j=1;j<=tot;j++){
int t;
scanf("%d",&t);
T.insert(pos+j-1,t);
}
}
else if(ord[0]=='D') T.erase(pos,pos+tot-1);
else if(ord[0]=='M'&&ord[2]=='K'){
int t;
scanf("%d",&t);
T.change(pos,pos+tot-1,t);
}
else if(ord[0]=='R') T.reverse(pos,pos+tot-1);
else if(ord[0]=='G') T.getsum(pos,pos+tot-1);
else T.maxsum();
}
return 0;
}