#include<bits/stdc++.h>
#define N 2000005
#define INF 2000001
using namespace std;
int n,pos;
char s[N];
int root,tot,val[N],ch[N][2],size[N],fa[N];
int a[N];
//操作支持:
//找rank
//插入,直接建成平衡树
//删除,断开,垃圾回收
//输出
int newnode(){
return ++tot;
}
void clear(int x){
ch[x][0]=ch[x][1]=fa[x]=size[x]=val[x]=0;
}
bool get(int x){
return x==ch[fa[x]][1];
}
void push_up(int x){
size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
void rotate(int x){
int y=fa[x],z=fa[y],chk=get(x);
if(z) ch[z][ch[z][1]==y]=x;
ch[y][chk]=ch[x][chk^1];
fa[ch[x][chk^1]]=y;
ch[x][chk^1]=y;
fa[y]=x;
fa[x]=z;
push_up(y);
push_up(x);
}
void splay(int x,int goal){
for(int f;f=fa[x],f!=goal;rotate(x)){
if(fa[f]) rotate(get(f)==get(x)?f:x);
}
if(!goal) root=x;
}
int build(int f,int l,int r){
if(l>r) return 0;
int mid=(l+r)>>1;
int x=newnode();
fa[x]=f;
val[x]=a[mid];
ch[x][0]=build(x,l,mid-1);
ch[x][1]=build(x,mid+1,r);
push_up(x);
return x;
}
int queryrank(int k){
int x=root;
while(1){
//cout<<ch[x][0]<<' '<<size[]<<endl;
if(k<=size[ch[x][0]]&&ch[x][0]) x=ch[x][0];
else{
k-=size[ch[x][0]]+1;
if(k<=0){
splay(x,0);
return x;
}
x=ch[x][1];
}
}
}
void insert(int len){
for(int i=1;i<=len;++i) {
s[i]=getchar();
if(s[i]=='\n'||s[i]=='\r') --i;
}
for(int i=1;i<=len;i++) a[i]=s[i]-32;
int x=queryrank(pos),y=queryrank(pos+1),p=build(0,1,len);
splay(x,0);
splay(y,x);
ch[y][0]=p;
fa[p]=y;
push_up(y);
push_up(x);
}
void del(int len){
int x=queryrank(pos),y=queryrank(pos+len+1);
splay(x,0);
splay(y,x);
int p=ch[y][0];
ch[y][0]=0;
push_up(y);
push_up(x);
}
void print(int x){
if(ch[x][0]) print(ch[x][0]);
if(x!=1&&x!=2){
char c=val[x]+32;
putchar(c);
}
if(ch[x][1]) print(ch[x][1]);
}
int main(){
scanf("%d",&n);
pos=1;
a[1]=0,a[2]=INF;
root=build(0,1,2);
while(n--){
char op[10];
int x;
scanf("%s",op);
if(op[0]=='I'){
scanf("%d",&x);
insert(x);
}
if(op[0]=='M'){
scanf("%d",&x);
pos=x+1;
}
if(op[0]=='D'){
scanf("%d",&x);
del(x);
}
if(op[0]=='G'){
scanf("%d",&x);
int a=queryrank(pos),b=queryrank(pos+x+1);
splay(a,0);
splay(b,a);
print(ch[b][0]);
puts("");
}
if(op[0]=='P') pos--;
if(op[0]=='N') pos++;
//splay(pos,0);
// print(root);
// puts("");
}
return 0;
}
这是我的代码,我在最后随便加了个 splay 就过了另外两个点。到底该怎么搞,才能保证 splay 复杂度正确。也可能我的代码本身是有问题的