• 「luogu2596 」[ZJOI2006]书架


    用平衡树维护每本书的位置

      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
    ",find(root,bookpos[t1]));
    108         }else{
    109             t1=read();
    110             printf("%d
    ",kth(root,t1));
    111         }
    112     }
    113     return 0;
    114 }
  • 相关阅读:
    ArcGIS for Android地图控件的5大常见操作
    adb开启不了解决方案
    Eclipse中通过Android模拟器调用OpenGL ES2.0函数操作步骤
    解决 Your project contains error(s),please fix them before running your application问题
    二路归并算法实现
    字符串全排列
    python连接MySQL
    .net常考面试题
    win7 web开发遇到的问题-由于权限不足而无法读取配置文件,无法访问请求的页面
    int.Parse()与int.TryParse()
  • 原文地址:https://www.cnblogs.com/mycups/p/8533372.html
Copyright © 2020-2023  润新知