BZOJ1507升级版,依旧是Splay,记得当时从头写了一遍…
AC code:
#include <cstdio>
#include <cstdlib>
#include <cstring>
const int N=2000000;
int n,pos;
char text[N];
struct Snode
{
int tot;
char ch;
bool rev;
Snode *Prev,*Ch[2];
};
struct Splay
{
Snode *NIL,*root,*pool;
Splay(int size)
{
pool=(Snode*)malloc(size*sizeof(Snode));
NIL=root=pool++;
NIL->tot=0;
NIL->Ch[0]=NIL->Ch[1]=NULL;
}
void rotate(Snode *x,bool type)
{
Snode *y=x->Prev,*z=y->Prev,*b=x->Ch[type^1];
b->Prev=y;
y->Prev=x;
x->Prev=z;
y->Ch[type]=b;
x->Ch[type^1]=y;
if(z->Ch[0]==y) z->Ch[0]=x;
if(z->Ch[1]==y) z->Ch[1]=x;
x->tot=y->tot;
y->tot=y->Ch[0]->tot+y->Ch[1]->tot+1;
}
void splay(Snode *x,Snode *obj)
{
while(x->Prev!=obj){
Snode *y=x->Prev,*z=y->Prev;
if(z==obj){
if(y->Ch[0]==x) rotate(x,0);
else 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;
}
void update(Snode *p)
{
if(!p->rev) return ;
p->Ch[0]->rev^=1;
p->Ch[1]->rev^=1;
Snode *t=p->Ch[0];
p->Ch[0]=p->Ch[1];
p->Ch[1]=t;
p->rev=0;
}
Snode* getnod(int k)
{
update(root);
Snode *p=root;
while(p->Ch[0]->tot+1!=k){
if(p->Ch[0]->tot>=k) p=p->Ch[0];
else{
k-=p->Ch[0]->tot+1;
p=p->Ch[1];
}
update(p);
}
return p;
}
void insert(char c,int k)
{
Snode **p;
Snode *last=NIL;
if(root==NIL) p=&root;
else if(k==1){
splay(getnod(1),NIL);
p=&root->Ch[0];
root->tot++;
last=root;
}
else if(k==root->tot+1){
splay(getnod(root->tot),NIL);
p=&root->Ch[1];
root->tot++;
last=root;
}
else{
splay(getnod(k-1),NIL);
splay(getnod(k),root);
p=&root->Ch[1]->Ch[0];
root->Ch[1]->tot++;
root->tot++;
last=root->Ch[1];
}
*p=pool++;
(*p)->ch=c;
(*p)->rev=0;
(*p)->tot=1;
(*p)->Prev=last;
(*p)->Ch[0]=(*p)->Ch[1]=NIL;
}
void erase(int L,int R)
{
if(L==1&&R==root->tot) root=NIL;
else if(L==1){
splay(getnod(R+1),NIL);
root->tot-=root->Ch[0]->tot;
root->Ch[0]=NIL;
}
else if(R==root->tot){
splay(getnod(L-1),NIL);
root->tot-=root->Ch[1]->tot;
root->Ch[1]=NIL;
}
else{
splay(getnod(L-1),NIL);
splay(getnod(R+1),root);
root->tot-=root->Ch[1]->Ch[0]->tot;
root->Ch[1]->tot-=root->Ch[1]->Ch[0]->tot;
root->Ch[1]->Ch[0]=NIL;
}
}
void reverse(int L,int R)
{
if(L==1&&R==root->tot) root->rev^=1;
else if(L==1){
splay(getnod(R+1),NIL);
root->Ch[0]->rev^=1;
}
else if(R==root->tot){
splay(getnod(L-1),NIL);
root->Ch[1]->rev^=1;
}
else{
splay(getnod(L-1),NIL);
splay(getnod(R+1),root);
root->Ch[1]->Ch[0]->rev^=1;
}
}
};
int main()
{
Splay T(N);
scanf("%d",&n);
for(int i=1;i<=n;i++){
char ord[11];
scanf("%s",ord);
if(!strcmp(ord,"Prev")) pos--;
else if(!strcmp(ord,"Next")) pos++;
else if(!strcmp(ord,"Get")){
T.splay(T.getnod(pos+1),T.NIL);
printf("%c\n",T.root->ch);
}
else{
int m;
scanf("%d",&m);
if(!strcmp(ord,"Move")) pos=m;
else if(!strcmp(ord,"Delete")) T.erase(pos+1,pos+m);
else if(!strcmp(ord,"Rotate")) T.reverse(pos+1,pos+m);
else{
for(int j=0;j<m;j++){
scanf("%c",&text[j]);
if(text[j]=='\n') j--;
}
for(int j=0;j<m;j++) T.insert(text[j],pos+j+1);
}
}
}
return 0;
}