BZOJ1861 [Zjoi2006]Book 书架
Splay维护操作。
学习了一个很好的remove操作。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=8e4+5; 4 const int inf=1e9; 5 int fa[N],c[N][2],size[N],pos[N],a[N],v[N],n,m,rt; 6 void update(int x) 7 { 8 size[x]=size[c[x][0]]+size[c[x][1]]+1; 9 } 10 void rotate(int x,int &k) 11 { 12 int y=fa[x],z=fa[y]; 13 int l=(c[y][1]==x);int r=l^1; 14 if(y==k)k=x;else c[z][c[z][1]==y]=x; 15 fa[x]=z;fa[y]=x;fa[c[x][r]]=y; 16 c[y][l]=c[x][r];c[x][r]=y; 17 update(y);update(x); 18 } 19 void splay(int x,int &k) 20 { 21 while(x!=k) 22 { 23 int y=fa[x],z=fa[y]; 24 if(y!=k) 25 { 26 if(x==c[y][0]^y==c[z][0])rotate(x,k); 27 else rotate(y,k); 28 } 29 rotate(x,k); 30 } 31 } 32 int find(int x,int k) 33 { 34 if(size[c[x][0]]+1==k)return x; 35 else if(size[c[x][0]]>=k)return find(c[x][0],k); 36 else return find(c[x][1],k-size[c[x][0]]-1); 37 } 38 void del(int k) 39 { 40 int x=find(rt,k-1);int y=find(rt,k+1); 41 splay(x,rt);splay(y,c[x][1]); 42 int z=c[y][0];c[y][0]=0;fa[z]=size[z]=0; 43 update(y);update(x); 44 } 45 void remove(int q,int w) 46 { 47 int k=pos[q],rank,x,y; 48 49 splay(k,rt);rank=size[c[rt][0]]+1; 50 del(rank); 51 if(w==inf)x=find(rt,n),y=find(rt,n+1); 52 else if(w==-inf)x=find(rt,1),y=find(rt,2); 53 else x=find(rt,rank+w-1),y=find(rt,rank+w); 54 splay(x,rt);splay(y,c[x][1]); 55 size[k]=1;fa[k]=y;c[y][0]=k; 56 update(y);update(x); 57 } 58 void build(int l,int r,int f) 59 { 60 if(l>r)return; 61 int mid=l+r>>1; 62 fa[mid]=f;c[f][mid>=f]=mid;v[mid]=a[mid]; 63 if(l==r) 64 { 65 size[l]=1;return; 66 } 67 build(l,mid-1,mid);build(mid+1,r,mid); 68 update(mid); 69 return; 70 } 71 int main() 72 { 73 scanf("%d%d",&n,&m); 74 for(int i=2;i<=n+1;++i) 75 { 76 scanf("%d",&a[i]);pos[a[i]]=i; 77 } 78 build(1,n+2,0);rt=(n+3)>>1;char s[10];int k,ss,t; 79 for(int i=1;i<=m;++i) 80 { 81 scanf("%s",s); 82 if(s[0]=='Q') 83 { 84 scanf("%d",&k); 85 printf("%d\n",v[find(rt,k+1)]); 86 } 87 else if(s[0]=='T') 88 { 89 scanf("%d",&k); 90 remove(k,-inf); 91 } 92 else if(s[0]=='B') 93 { 94 scanf("%d",&k); 95 remove(k,inf); 96 } 97 else if(s[0]=='I') 98 { 99 scanf("%d%d",&ss,&t);remove(ss,t); 100 } 101 else 102 { 103 scanf("%d",&k);k=pos[k]; 104 splay(k,rt); 105 printf("%d\n",size[c[rt][0]]-1); 106 } 107 } 108 return 0; 109 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。