BZOJ 1507 [NOI2003]Editor
2017.08.24
2017.08.24
给你一个文本,让你维护它,支持以下操作:插入字符串;删除字符串;输出字符。
直接Splay维护一下就可以完美解决了qwq
注意对于这种一次插入一大堆东西的一定要O(N)建一棵新Splay树之后再合并到根节点右儿子的左儿子的位置,之后就可以了。1269查询的是字符串,跑一次DFS中序遍历输出就可以了。
#include <bits/stdc++.h>
using namespace std;
int n,inx,point,siz[2100000],son[2100000][2],fa[2100000],root,tot=2;
char mode[10],s[2100000],val[2100000];
bool rev[2100000];
void rever(int pos) {swap(son[pos][0],son[pos][1]),rev[pos]^=1;return;}
void pushup(int pos) {siz[pos]=siz[son[pos][0]]+siz[son[pos][1]]+1;return;}
void pushdown(int pos) {if(rev[pos]) rever(son[pos][0]),rever(son[pos][1]),rev[pos]=0;return;}
void rotate(int &rt,int x)
{
int y=fa[x],z=fa[y],l=(son[y][1]==x),r=l^1;
if(y==rt) rt=x;
else son[z][son[z][1]==y]=x;
fa[x]=z,fa[y]=x,fa[son[x][r]]=y,son[y][l]=son[x][r],son[x][r]=y;
pushup(y),pushup(x);
}
void splay(int &k,int x)
{
while(x!=k)
{
int y=fa[x],z=fa[y];
if(y!=k)
{
if((son[y][0]==x)^(son[z][0]==y)) rotate(k,x);
else rotate(k,y);
}
rotate(k,x);
}
}
int lookfor(int pos,int tx)
{
pushdown(pos);
if(tx<=siz[son[pos][0]]) return lookfor(son[pos][0],tx);
if(tx>siz[son[pos][0]]+1) return lookfor(son[pos][1],tx-siz[son[pos][0]]-1);
return pos;
}
int split(int tx,int ty)
{
splay(root,lookfor(root,tx)),splay(son[root][1],lookfor(root,ty+2));
return son[son[root][1]][0];
}
void readin()
{
char tmp=getchar();
while(tmp<32||tmp>126) tmp=getchar();
inx--;
for(int i=0;i<inx;++i)
{
s[i]=tmp,tmp=getchar();
while(tmp=='\n') tmp=getchar();
}
s[inx]=tmp;
inx++;
}
int build(int l,int r)
{
if(l>r) return 0;
int mid=(l+r)>>1;
son[mid][0]=build(l,mid-1);
son[mid][1]=build(mid+1,r);
fa[son[mid][0]]=fa[son[mid][1]]=mid;
pushup(mid);
return mid;
}
void dfs(int pos)
{
if(pos==0) return;
dfs(son[pos][0]);
printf("%c",val[pos]);
dfs(son[pos][1]);
}
int main()
{
scanf("%d",&n);
root=build(1,2);
tot=2;
while(n--)
{
scanf("%s",mode);
switch(mode[0])
{
case 'M': {scanf("%d",&inx);point=inx;break;}
case 'I':
{
scanf("%d",&inx);
readin();
split(point+1,point);
for(int i=0;i<inx;++i) val[tot+i+1]=s[i];
son[son[root][1]][0]=build(tot+1,tot+inx),fa[son[son[root][1]][0]]=son[root][1];
pushup(son[root][1]);
pushup(root);
tot+=inx;
break;
}
case 'D':
{
scanf("%d",&inx);
split(point+1,point+inx);
son[son[root][1]][0]=0;
pushup(son[root][1]);
pushup(root);
break;
}
case 'G':
{
scanf("%d",&inx);
dfs(split(point+1,point+inx));
printf("\n");
break;
}
case 'P': {point--;break;}
case 'N': {point++;break;}
}
}
return 0;
}