标签:
题意:
维护一个序列,支持移动元素,查询元素是第几个,查询第k个元素编号。
题解:
可以用treap和splay,我写的是splay。移动元素就是先删一个节点在将这个节点插入到对应位置,注意各种分操作(如splay、find)的次序性。反思:本弱又WA又T,最后自己造了一个极限数据发现死循环了,对着大数据调了半天才发现是分操作次序不当导致错误。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) for(int i=j;i<=k;i++) 5 #define maxn 80100 6 using namespace std; 7 8 int ch[maxn][2],fa[maxn],v[maxn],sz[maxn],pos[maxn],root,book[maxn],tot,n,m; 9 inline int read(){ 10 char ch=getchar(); int f=1,x=0; 11 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();}; 12 while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar(); 13 return f*x; 14 } 15 inline void update(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;} 16 void rotate(int x){ 17 if(!x||!fa[x])return; int a=fa[x],b=fa[fa[x]]; bool c=x==ch[fa[x]][1],d=a==ch[fa[a]][1]; 18 if(b)ch[b][d]=x; fa[x]=b; ch[a][c]=ch[x][!c]; if(ch[x][!c])fa[ch[x][!c]]=a; ch[x][!c]=a; fa[a]=x; 19 update(a); update(x); if(b)update(b); 20 } 21 void splay(int x,int y){ 22 if(x==y)return; int z=fa[y]; 23 while(fa[x]!=z){ 24 if(fa[x]!=y)(x==ch[fa[x]][1])^(fa[x]==ch[fa[fa[x]]][1])?rotate(x):rotate(fa[x]); 25 rotate(x); 26 } 27 if(root==y)root=x; 28 } 29 void build(int x,int l,int r){ 30 int mid=l+r>>1; v[x]=book[mid]; pos[book[mid]]=x; 31 if(l<=mid-1)ch[x][0]=++tot,build(ch[x][0],l,mid-1),fa[ch[x][0]]=x; 32 if(mid+1<=r)ch[x][1]=++tot,build(ch[x][1],mid+1,r),fa[ch[x][1]]=x; 33 update(x); 34 } 35 int querynum(int x,int k){ 36 if(k<=sz[ch[x][0]])return querynum(ch[x][0],k); 37 if(k==sz[ch[x][0]]+1)return x; 38 return querynum(ch[x][1],k-sz[ch[x][0]]-1); 39 } 40 int queryrank(int x){ 41 splay(x,root); return sz[ch[x][0]]; 42 } 43 int pre(int y){ 44 splay(y,root); return querynum(ch[y][0],sz[ch[y][0]]); 45 } 46 int nex(int y){ 47 splay(y,root); return querynum(ch[y][1],1); 48 } 49 void add(int x,int y,int z){ 50 splay(y,root); splay(x,ch[root][0]); ch[x][1]=z; fa[z]=x; update(x); update(root); 51 } 52 void erase(int z){ 53 int x=pre(z),y=nex(z); splay(y,root); splay(x,ch[root][0]); ch[x][1]=0; fa[z]=0; update(x); update(root); 54 } 55 void top(int s){ 56 int x=pos[s]; erase(x); int y=querynum(root,1),z=nex(y); add(y,z,x); 57 } 58 void bottom(int s){ 59 int x=pos[s]; erase(x); int y=querynum(root,sz[root]-1),z=nex(y); add(y,z,x); 60 } 61 void insert(int s,int t){ 62 int a1=pos[s],a2=queryrank(a1)+t; erase(a1); int a3=querynum(root,a2),a4=nex(a3); add(a3,a4,a1); 63 } 64 int ask(int s){return queryrank(pos[s])-1;} 65 int query(int s){return v[querynum(root,s+1)];} 66 int main(){ 67 n=read(); m=read(); inc(i,2,n+1)book[i]=read(); tot=root=1; build(root,1,n+2); 68 inc(i,1,m){ 69 char opt[8]; scanf("%s",opt); 70 if(opt[0]==‘T‘){int a=read(); top(a);} 71 if(opt[0]==‘B‘){int a=read(); bottom(a);} 72 if(opt[0]==‘I‘){int a=read(),b=read(); insert(a,b);} 73 if(opt[0]==‘A‘){int a=read(); printf("%d\n",ask(a));} 74 if(opt[0]==‘Q‘){int a=read(); printf("%d\n",query(a));} 75 } 76 return 0; 77 }
20160811
标签:
原文地址:http://www.cnblogs.com/YuanZiming/p/5769472.html