|
- #include <bits/stdc++.h>
- using namespace std;
- const int mm=2100000;
- struct Node
- {
- char val;
- int fa,s[2],sz;
- } a[mm];
- int root,tot,curpos,offset;
- char s[mm];
- void ArrayPr() /// 调试监视使用
- {
- cout<<endl<<" i ";
- for (int i=1; i<=tot; i++) cout<<setw(3)<<i;
- cout<<endl<<"val ";
- for (int i=1; i<=tot; i++) cout<<setw(3)<<a[i].val;
- cout<<endl<<" s0 ";
- for (int i=1; i<=tot; i++) cout<<setw(3)<<a[i].s[0];
- cout<<endl<<" s1 ";
- for (int i=1; i<=tot; i++) cout<<setw(3)<<a[i].s[1];
- cout<<endl<<" fa ";
- for (int i=1; i<=tot; i++) cout<<setw(3)<<a[i].fa;
- cout<<endl<<" sz ";
- for (int i=1; i<=tot; i++) cout<<setw(3)<<a[i].sz;
- cout<<endl;
- }
- void pushup(int x)
- {
- int l=a[x].s[0],r=a[x].s[1];
- a[x].sz=a[l].sz+a[r].sz+1;
- }
- int son(int x)
- {
- int y=a[x].fa;
- return a[y].s[1]==x;
- }
- void R(int x)
- {
- int y=a[x].fa;
- int z=a[y].fa;
- int k=son(x);
- int v=a[x].s[k^1];
- a[y].s[k]=v,a[v].fa=y;
- a[z].s[son(y)]=x,a[x].fa=z;
- a[x].s[k^1]=y,a[y].fa=x;
- pushup(y),pushup(x);
- }
- void Splay(int x,int rt=root) ///把x旋到rt的位置 默认rt是根
- {
- rt=a[rt].fa;
- int y,z;
- while(a[x].fa!=rt)
- {
- y=a[x].fa,z=a[y].fa;;
- if(z!=rt)
- if(son(x)==son(y))R(y);
- else R(x);
- R(x);
- }
- if(rt==0)root=x;
- }
- int Build(int l,int r) ///把s串L-R之间的建树
- {
- if (l>r)return 0;
- if (l==r)
- {
- a[offset+l].sz=1;
- return l;
- }
- if (l<r)
- {
- int m=(l+r)/2;
- int tl=0,tr=0;
- if (m-1>=l)
- {
- tl=Build(l,m-1),a[offset+tl].fa=offset+m,a[offset+m].s[0]=offset+tl;
- }
- if (m+1<=r)
- {
- tr=Build(m+1,r),a[offset+tr].fa=offset+m,a[offset+m].s[1]=offset+tr;
- }
- a[offset+m].sz=r-l+1;
- return m;
- }
- }
- int Getkth(int rt, int x) ///在RT子树中找第k小
- {
- int l=a[a[rt].s[0]].sz; /// RT的左儿子下的个数
- if(l+1==x)
- {
- Splay(rt,root);
- return rt;
- }
- if(l+1>x) return Getkth(a[rt].s[0], x); ///左儿子里去找
- if(l+1<x) return Getkth(a[rt].s[1], x-(l+1));
- }
- void NewEmpty()/// 建新的假树
- {
- a[1].val=a[2].val='@';
- a[1].s[0]=a[2].s[0]=a[2].s[1]=0,a[1].s[1]=2;
- a[1].fa=0,a[2].fa=1;
- a[1].sz=2,a[2].sz=1;
- root=1,tot=2,curpos=0;
- }
- void BSTPr(int x)
- {
- int l=a[x].s[0],r=a[x].s[1];
- if (l>0) BSTPr(l);
- printf("%c",a[x].val);
- if (r>0) BSTPr(r);
- }
- int main()
- {
- int n;
- scanf("%d",&n);
- NewEmpty();
- while (n--)
- {
- char opt[10];
- scanf("%s", opt);
- if (opt[0]=='M')
- {
- int k;
- scanf("%d",&k);
- curpos=k;
- }
- if (opt[0]=='I')
- {
- int l,i=1;
- scanf("%d",&l);
- char ch;
- s[0]='#';
- while (i<=l)
- {
- ch=getchar();
- while(ch<32||ch>126) ch=getchar();
- s[i++]=ch;
- }
- offset=tot;
- tot+=l;
- for (i=1;i<=l;i++) a[offset+i].val=s[i];
- int tm=offset+Build(1,l);
- int L=Getkth(root,curpos+1); ///这个偏移要注意 光标位置0 就把一号假节点转到根
- int R=Getkth(root,curpos+2);
- Splay(L,root),Splay(R,a[root].s[1]);
- a[R].s[0]=tm,a[tm].fa=R;
- pushup(R),pushup(L);
- }
- if (opt[0]=='G')
- {
- int k;
- scanf("%d",&k);
- int L=Getkth(root,curpos+1);
- int R=Getkth(root,curpos+k+2);
- Splay(L,root),Splay(R,a[root].s[1]);
- BSTPr(a[R].s[0]);
- printf("\n");
- }
- if (opt[0]=='D')
- {
- int k;
- scanf("%d",&k);
- int L=Getkth(root,curpos+1);
- int R=Getkth(root,curpos+k+2);
- Splay(L,root),Splay(R,a[root].s[1]);
- a[R].s[0]=0;
- pushup(R),pushup(L);
- }
- if (opt[0]=='P') curpos--;
- if (opt[0]=='N') curpos++;
- ///BSTPr(root);cout<<endl;
- }
- return 0;
- }
- /*
- 10
- Insert 10
- abcdefghij
- Move 5
- Insert 10
- 0123456789
- Move 3
- Ins 2
- **
- Move 10
- In 3
- %%%
- Del 3
- */
复制代码 |
|