用平衡树维护每本书的位置
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=80010; 4 int n,m,maxpos,minpos,book[N<<2],bookpos[N]; 5 int root,fa[N<<2],ch[N<<2][2],siz[N<<2],pos[N<<2],id[N<<2],totnode; 6 inline int read(){ 7 int x=0,w=1;char c=0; 8 while(c<‘0‘||c>‘9‘){if(c==‘-‘) w=-1;c=getchar();} 9 while(c>=‘0‘&&c<=‘9‘) x=x*10+c-48,c=getchar(); 10 return x*w; 11 } 12 inline void updata(int k){ 13 siz[k]=1; 14 if(ch[k][0]) siz[k]+=siz[ch[k][0]]; 15 if(ch[k][1]) siz[k]+=siz[ch[k][1]]; 16 return; 17 } 18 int build(int dad,int l,int r){ 19 if(l>r) return 0; 20 int mid=(l+r)>>1; 21 int nownode=++totnode; 22 fa[nownode]=dad,pos[nownode]=mid,id[nownode]=book[mid]; 23 ch[nownode][0]=build(nownode,l,mid-1),ch[nownode][1]=build(nownode,mid+1,r); 24 updata(nownode); 25 return nownode; 26 } 27 inline bool which(int k){return ch[fa[k]][1]==k;} 28 inline void rotate(int k){ 29 int old=fa[k],oldf=fa[old],whnow=which(k),whold=which(old); 30 ch[old][whnow]=ch[k][whnow^1]; 31 if(ch[k][whnow^1])fa[ch[k][whnow^1]]=old; 32 fa[old]=k,ch[k][whnow^1]=old,fa[k]=oldf; 33 if(oldf) ch[oldf][whold]=k; 34 if(!fa[k]) root=k; 35 updata(old);updata(k); 36 return; 37 } 38 inline void splay(int k,int aim){ 39 for(int i=fa[k];fa[k]!=aim;i=fa[k]) 40 rotate(fa[i]!=aim&&which(k)==which(i)?i:k); 41 return; 42 } 43 int find(int k,int x){ //返回位置为x的书上面有多少本 44 if(!k) return 0; 45 if(pos[k]==x){int res=siz[ch[k][0]];splay(k,0);return res;} 46 if(pos[k]>x) return find(ch[k][0],x); 47 int tmp=siz[ch[k][0]]; 48 return tmp+1+find(ch[k][1],x); 49 } 50 int kth(int now,int k){//返回第k本书的编号 51 if(!now) return 0; 52 if(siz[ch[now][0]]==k-1) return id[now]; 53 if(siz[ch[now][0]]>=k) return kth(ch[now][0],k); 54 return kth(ch[now][1],k-siz[ch[now][0]]-1); 55 } 56 inline int get(int k,bool b){ //b为0返回前驱节点,b为1返回后继节点 57 if(!ch[k][b]) return 0; 58 int now=ch[k][b]; 59 while(ch[now][b^1]) now=ch[now][b^1]; 60 return now; 61 } 62 void move(int s,bool b){ 63 find(root,bookpos[s]); 64 pos[root]=bookpos[s]=b?++maxpos:--minpos; 65 if(!ch[root][b]) return; 66 if(!ch[root][b^1]){ 67 swap(ch[root][0],ch[root][1]); //!! 68 return; 69 } 70 book[bookpos[s]]=s; 71 int nxt=get(root,b^1); 72 if(!nxt){swap(ch[root][0],ch[root][1]);return;} 73 splay(nxt,root); 74 ch[nxt][b]=ch[root][b]; 75 fa[ch[root][b]]=nxt,ch[root][b]=0; 76 updata(ch[root][b^1]);updata(root); 77 return; 78 } 79 void nodeswap(int s,bool b){ 80 find(root,bookpos[s]); 81 int nxt=get(root,b); 82 if(!nxt) return; 83 swap(id[nxt],id[root]); 84 swap(book[pos[root]],book[pos[nxt]]); 85 swap(bookpos[id[nxt]],bookpos[id[root]]); 86 return; 87 } 88 int main(){ 89 char opt[10]; 90 int t1,t2; 91 n=read(),m=read(); 92 minpos=m+1,maxpos=n+m; 93 for(int i=m+1;i<=n+m;i++) book[i]=read(),bookpos[book[i]]=i; 94 root=1;build(0,m+1,n+m); 95 for(int i=1;i<=m;i++){ 96 scanf("%s",opt); 97 if(opt[0]==‘T‘){ 98 t1=read();move(t1,0); 99 }else if(opt[0]==‘B‘){ 100 t1=read();move(t1,1); 101 }else if(opt[0]==‘I‘){ 102 t1=read(),t2=read(); 103 if(t2==-1) nodeswap(t1,0); 104 else if(t2==1) nodeswap(t1,1); 105 }else if(opt[0]==‘A‘){ 106 t1=read(); 107 printf("%d\n",find(root,bookpos[t1])); 108 }else{ 109 t1=read(); 110 printf("%d\n",kth(root,t1)); 111 } 112 } 113 return 0; 114 }