Splay序列维护的模板题了……为了便于处理边界情况,我们可以先插入两个空格当作最左端和最右端,然后……其实本题主要考察的就是Build、splay和Findkth这三个操作,我们可以实现一个splay(x,s)操作,使x结点旋转到s结点的下方(如果s为0则x旋转到根),这样可以方便地提取出要处理的区间。

  这份模板我还是比较满意的,因为写的没那么长……

  1 /**************************************************************
  2     Problem: 1269
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:1236 ms
  7     Memory:46220 kb
  8 ****************************************************************/
  9  
 10 //BZOJ 1269
 11 #include<vector>
 12 #include<cstdio>
 13 #include<cstring>
 14 #include<cstdlib>
 15 #include<iostream>
 16 #include<algorithm>
 17 #define rep(i,n) for(int i=0;i<n;++i)
 18 #define F(i,j,n) for(int i=j;i<=n;++i)
 19 #define D(i,j,n) for(int i=j;i>=n;--i)
 20 #define pb push_back
 21 using namespace std;
 22 inline int getint(){
 23     int v=0,sign=1; char ch=getchar();
 24     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
 25     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
 26     return v*sign;
 27 }
 28 const int N=2e6+1000,INF=~0u>>2;
 29 typedef long long LL;
 30 /******************tamplate*********************/
 31 int n;
 32 char s[N],v[N];
 33 int c[N][2],size[N],fa[N],root,tot;
 34 bool rev[N];
 35 #define L c[x][0]
 36 #define R c[x][1]
 37 void Push_up(int x){
 38     size[x]=size[L]+size[R]+1;
 39 }
 40 void Push_down(int x){
 41     if (rev[x]) {rev[L]^=rev[x]; rev[R]^=rev[x]; rev[x]=0; swap(L,R);}
 42 }
 43 void New_node(int &x,int f,int key){
 44     x=++tot;
 45     fa[x]=f; v[x]=key; 
 46     L=R=rev[x]=0;
 47     size[x]=1;
 48 }
 49 void Build(int &x,int f,int l,int r){
 50     if (l>r) return;
 51     int m=l+r>>1;
 52     New_node(x,f,s[m]);
 53     Build(L,x,l,m-1);
 54     Build(R,x,m+1,r);
 55     Push_up(x);
 56 }
 57 void Rotate(int x){
 58     int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
 59     c[z][c[z][1]==y]=x;
 60     fa[x]=z; fa[y]=x; fa[c[x][r]]=y; 
 61     c[y][l]=c[x][r]; c[x][r]=y;
 62     Push_up(y);
 63 }
 64 int st[N],top;
 65 void Preview(int x){
 66     top=0; st[++top]=x;
 67     for(;fa[x];x=fa[x])
 68         st[++top]=fa[x];
 69     D(i,top,1) Push_down(st[i]);
 70 }
 71 void splay(int x,int s=0){
 72     int y;
 73     for(Preview(x);fa[x]!=s;Rotate(x))
 74         if ((fa[y=fa[x]])!=s) Rotate(c[y][1]==x^c[fa[y]][1]==y ? x : y);
 75     Push_up(x);
 76     if (!s) root=x;
 77 }
 78 int kth(int x,int k){
 79     if (rev[x]) Push_down(x);
 80     if (size[L]+1==k) return x;
 81     else if (size[L]>=k) return kth(L,k);
 82     else return kth(R,k-size[L]-1);
 83 }
 84 int main(){
 85 #ifndef ONLINE_JUDGE
 86     freopen("1269.in","r",stdin);
 87     freopen("1269.out","w",stdout);
 88 #endif
 89     n=getint();
 90     s[0]=s[1]=' ';
 91     Build(root,0,0,1);
 92     int x,now=1; char cmd[10];
 93     F(i,1,n){
 94         scanf("%s",cmd);
 95 //      cout <<"cmd: "<<cmd<<endl;
 96         if (cmd[0]=='I'){
 97             x=getint();//gets(s);
 98             gets(s);
 99             splay(kth(root,now));
100             splay(kth(root,now+1),root);
101             Build(c[c[root][1]][0],c[root][1],0,x-1);
102         }else if (cmd[0]=='M'){
103             now=getint()+1;
104         }else if (cmd[0]=='D'){
105             x=getint();
106             splay(kth(root,now)); splay(kth(c[root][1],x+1),root);
107             c[c[root][1]][0]=0; Push_up(c[root][1]); Push_up(root);
108         }else if (cmd[0]=='R'){
109             x=getint();
110             splay(kth(root,now)); splay(kth(c[root][1],x+1),root);
111             rev[c[c[root][1]][0]]^=1;
112         }else if (cmd[0]=='G'){
113             printf("%c\n",v[kth(root,now+1)]);
114         }else if (cmd[0]=='N'){
115             now++;
116         }else if (cmd[0]=='P'){
117             now--;
118         }
119     }
120     return 0;
121 }
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-08-31
  • 2021-09-19
  • 2022-12-23
  • 2021-06-25
  • 2021-08-07
  • 2021-11-30
猜你喜欢
  • 2022-01-06
  • 2022-12-23
  • 2021-09-22
  • 2021-05-11
  • 2021-09-26
  • 2021-12-27
  • 2021-05-24
相关资源
相似解决方案