平衡树裸题。光标位置直接修改就行,然后就区间插入删除,直接splay就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
char ch=getchar();int f=0,x=1;
while(ch<'0'||ch>'9'){if(ch=='-') x=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){f=(f<<1)+(f<<3)+ch-'0';ch=getchar();}
return f*x;
}
int n,m,sz,rt,pos,cnt;
int fa[3000005],ch[3000005][2],id[3000005];
int size[3000005];char w[3000005];
char op[15];
void pushup(int x)
{
size[x]=1+size[ch[x][0]]+size[ch[x][1]];
}
void rotate(int x,int &k)
{
int y=fa[x],z=fa[y],l,r;
if(ch[y][0]==x) l=0;else l=1;r=l^1;
if(y==k) k=x;
else
{
if(ch[z][0]==y) ch[z][0]=x;
else ch[z][1]=x;
}
fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
ch[y][l]=ch[x][r];ch[x][r]=y;
pushup(y);pushup(x);
}
void splay(int x,int &k)
{
while(x!=k)
{
int y=fa[x],z=fa[y];
if(y!=k)
{
if(ch[z][0]==y^ch[y][0]==x) rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
int getmin(int x)
{
while(ch[x][0]) x=ch[x][0];
return x;
}
int kth(int x,int k)
{
int temp=size[ch[x][0]];
if(temp+1==k) return x;
if(k<=temp) return kth(ch[x][0],k);
return kth(ch[x][1],k-temp-1);
}
void build(int &x,int fa1,int l,int r,char *s)
{
if(l>r) return;
int mid=l+r>>1;
x=++sz;
ch[x][0]=ch[x][1]=size[x]=0;
fa[x]=fa1;
w[x]=s[mid];
build(ch[x][0],x,l,mid-1,s);
build(ch[x][1],x,mid+1,r,s);
pushup(x);
}
void insert(char *s,int l)
{
int x=kth(rt,pos);
splay(x,rt);
x=getmin(ch[rt][1]);
splay(x,ch[rt][1]);
build(ch[x][0],x,0,l-1,s);
}
char s[3000005];
void out(int x,int k)
{
if(!ch[x][0]&&!ch[x][1])
{
cnt++;
if(cnt>k) return;
printf("%c",w[x]);
return;
}
if(ch[x][0]) out(ch[x][0],k);
cnt++;
if(cnt>k) return;
printf("%c",w[x]);
if(ch[x][1]) out(ch[x][1],k);
}
void del(int k)
{
//cout<<k<<" ";
int x=kth(rt,pos);
splay(x,rt);
x=kth(rt,pos+k+1);
splay(x,ch[rt][1]);
fa[ch[x][0]]=0;
ch[x][0]=0;
pushup(x);
pushup(rt);
}
void solve(int k)
{
int x=kth(rt,pos);
splay(x,rt);
cnt=0;
out(ch[rt][1],k);
puts("");
}
int main()
{
n=read();pos=1;
build(rt,0,0,1," ");
while(n--)
{
scanf("%s",op+1);
if(op[1]=='P') pos--;
else if(op[1]=='N') pos++;
else if(op[1]=='M')
{
int x=read();
pos=x+1;
}
else if(op[1]=='I')
{
int x=read();
for(int i=0;i<x;i++)
{
s[i]=getchar();
if(s[i]=='\n') i--;
}
insert(s,x);
}
else if(op[1]=='D')
{
int x=read();
del(x);
}
else
{
int x=read();
solve(x);
}
}
}