1. 程式人生 > >「luogu2596 」[ZJOI2006]書架

「luogu2596 」[ZJOI2006]書架

turn ret tchar pda min inline return log bsp

用平衡樹維護每本書的位置

  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 }

「luogu2596 」[ZJOI2006]書架