码迷,mamicode.com
首页 > 其他好文 > 详细

解题:ZJOI 2006 书架

时间:2018-11-16 21:33:26      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:class   ace   har   targe   return   can   hide   hup   zjoi 2006   

题面

学习了如何在维护序列的平衡树上查找某个数:按初始的顺序定个权值,然后每次找那个权值的DFS序即可。具体实现就是不停往上跳,然后是父亲的右儿子就加上父亲的左儿子,剩下的就是继续熟悉无旋树堆

技术分享图片
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 using namespace std;
  5 const int N=100005;
  6 int num[N],val[N],siz[N],anc[N],son[N][2],rnk[N];
  7 int n,m,w,x,y,z,rd,re,tot,pos,root; char ch[10];
  8 void Pushup(int nde)
  9 {
 10     siz[nde]=siz[son[nde][0]]+siz[son[nde][1]]+1;
 11     if(son[nde][0]) anc[son[nde][0]]=nde;
 12     if(son[nde][1]) anc[son[nde][1]]=nde;
 13 }
 14 int Create(int tsk)
 15 {
 16     siz[++tot]=1;
 17     val[tot]=tsk;
 18     num[tsk]=tot;
 19     rnk[tot]=rand();
 20     return tot;
 21 }
 22 int Merge(int x,int y)
 23 {
 24     if(!x||!y) return x+y;
 25     else if(rnk[x]<=rnk[y])
 26     {
 27         son[x][1]=Merge(son[x][1],y);
 28         Pushup(x); return x;    
 29     } 
 30     else 
 31     {
 32         son[y][0]=Merge(x,son[y][0]);
 33         Pushup(y); return y;
 34     }
 35 }
 36 void Split(int nde,int &x,int &y,int tsk)
 37 {
 38     if(!nde) x=y=0;
 39     else
 40     {
 41         if(siz[son[nde][0]]<tsk)
 42             x=nde,Split(son[nde][1],son[nde][1],y,tsk-siz[son[nde][0]]-1);
 43         else 
 44             y=nde,Split(son[nde][0],x,son[nde][0],tsk);
 45         Pushup(nde); 
 46     }
 47 }
 48 int Query(int nde)
 49 {
 50     int ret=siz[son[nde][0]]+1;
 51     while(anc[nde]) {
 52         if(nde==son[anc[nde]][1])
 53         ret+=siz[son[anc[nde]][0]]+1;
 54         nde=anc[nde];
 55     }
 56     return ret;
 57 }
 58 void DFS(int nde)
 59 {
 60     if(son[nde][0]) DFS(son[nde][0]);
 61     printf("->%d",val[nde]);
 62     if(son[nde][1]) DFS(son[nde][1]);
 63 }
 64 int main()
 65 {
 66     srand(20020513);
 67     scanf("%d%d",&n,&m);
 68     for(int i=1;i<=n;i++)
 69         scanf("%d",&rd),root=Merge(root,Create(rd));
 70     while(m--)
 71     {
 72         scanf("%s%d",ch,&rd),pos=Query(num[rd]); 
 73         if(ch[0]==T) 
 74         {
 75             Split(root,x,z,pos),Split(x,x,y,pos-1);
 76             root=Merge(Merge(y,x),z);
 77         }
 78         else if(ch[0]==B)
 79         {
 80             Split(root,x,z,pos),Split(x,x,y,pos-1);
 81             root=Merge(Merge(x,z),y);
 82         }
 83         else if(ch[0]==I)
 84         {
 85             scanf("%d",&re);
 86             if(re==-1)
 87             {
 88                 Split(root,w,z,pos),Split(w,w,y,pos-1); 
 89                 Split(w,w,x,pos-2); root=Merge(Merge(Merge(w,y),x),z);
 90             }
 91             else if(re==1)
 92             {
 93                 Split(root,y,z,pos+1),Split(y,x,y,pos);
 94                 Split(x,w,x,pos-1); root=Merge(Merge(Merge(w,y),x),z);
 95             }
 96         }
 97         else if(ch[0]==A)
 98             printf("%d\n",pos-1);
 99         else
100         {
101             Split(root,x,z,rd),Split(x,x,y,rd-1);
102             printf("%d\n",val[y]); 
103             root=Merge(Merge(x,y),z);
104         }
105     }
106     return 0;
107 }
View Code

 

解题:ZJOI 2006 书架

标签:class   ace   har   targe   return   can   hide   hup   zjoi 2006   

原文地址:https://www.cnblogs.com/ydnhaha/p/9971675.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!