• fhq_treap || BZOJ1861: [Zjoi2006]Book 书架 || Luogu P2596 [ZJOI2006]书架


    题面:P2596 [ZJOI2006]书架

    题解:记录每本书对应的节点编号

    普通fhq_treap无法查询一个权值的排名,所以在普通fhq_treap上多记录每个节点的父亲(可加在pushup函数中),

    查询时从该节点开始逐步往上跳,记录答案。

    其他操作都依附在该排名上。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<cstdlib>
      5 using namespace std;
      6 inline int rd(){
      7     int x=0,f=1;char c=getchar();
      8     while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
      9     while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
     10     return f*x;
     11 }
     12 const int maxn=(8e4)+50;
     13 int N,M,lc[maxn],rc[maxn],val[maxn],pr[maxn],tot=0,siz[maxn];
     14 int u,rt=0,s,t,x,y,z,id[maxn],fa[maxn],k;
     15 //id[i]表示编号为i的书所在的节点编号 
     16 char o[15];
     17 inline int New_node(int x){
     18     val[++tot]=x;
     19     siz[tot]=1;
     20     pr[tot]=rand();
     21     return tot;
     22 }
     23 inline void Pushup(int x){
     24     siz[x]=siz[lc[x]]+siz[rc[x]]+1;
     25     fa[lc[x]]=fa[rc[x]]=x;
     26     return;
     27 }
     28 inline void Split(int now,int k,int &x,int &y){
     29     if(!now){
     30         x=y=fa[x]=fa[y]=0;
     31         return;
     32     }
     33     if(siz[lc[now]]+1<=k){
     34         x=now;
     35         Split(rc[now],k-siz[lc[now]]-1,rc[now],y);
     36     }
     37     else {        
     38         y=now;
     39         Split(lc[now],k,x,lc[now]);
     40     }
     41     Pushup(now);
     42     return;
     43 }
     44 inline int Merge(int x,int y){
     45     if(!x||!y){
     46         fa[x]=fa[y]=x+y;
     47         return x+y;
     48     }
     49     if(pr[x]<pr[y]){
     50         rc[x]=Merge(rc[x],y);
     51         Pushup(x);
     52         return x;
     53     }
     54     else{
     55         lc[y]=Merge(x,lc[y]);
     56         Pushup(y);
     57         return y;
     58     }
     59 }
     60 inline int Find(int x){//寻找x节点上有多少书
     61     int sum=0;
     62     sum+=siz[lc[x]];
     63     while(x!=rt){
     64         if(rc[fa[x]]==x)sum+=siz[lc[fa[x]]]+1;
     65         x=fa[x];
     66     }
     67     return sum;
     68 }
     69 inline int Query(int k){
     70     int now=rt;
     71     while(now){
     72         if(k<=siz[lc[now]])now=lc[now];
     73         else if(k==siz[lc[now]]+1)return now;
     74         else k-=siz[lc[now]]+1,now=rc[now];
     75     }
     76     return 0;
     77 }
     78 int main(){
     79     srand(20030304);
     80     N=rd();M=rd();
     81     for(int i=1;i<=N;i++){
     82         u=rd();
     83         rt=Merge(rt,id[u]=New_node(u));
     84     }
     85     while(M--){
     86         scanf("%s",o); s=rd();
     87         if(o[0]=='T'){
     88             k=Find(id[s]);
     89             Split(rt,k+1,x,z);
     90             Split(x,k,x,y);
     91             rt=Merge(Merge(x,Merge(lc[y],rc[y])),z);
     92             rt=Merge(id[s],rt);
     93         }
     94         else if(o[0]=='B'){
     95             k=Find(id[s]);
     96             Split(rt,k+1,x,z);
     97             Split(x,k,x,y);
     98             rt=Merge(Merge(x,Merge(lc[y],rc[y])),z);
     99             rt=Merge(rt,id[s]);
    100         }
    101         else if(o[0]=='I'){
    102             t=rd();
    103             k=Find(id[s]);
    104             Split(rt,k+1,x,z);
    105             Split(x,k,x,y);
    106             rt=Merge(Merge(x,Merge(lc[y],rc[y])),z);
    107             Split(rt,k+t,x,y);
    108             rt=Merge(Merge(x,id[s]),y);
    109         }
    110         else if(o[0]=='A'){
    111             printf("%d
    ",Find(id[s]));    
    112         }
    113         else {//Q
    114             printf("%d
    ",val[Query(s)]);    
    115         }
    116     }
    117     return 0;
    118 }

    By:AlenaNuna

  • 相关阅读:
    C# 时间格式化
    新线程匿名方法的新用法
    响应类
    图灵API
    Xpath使用
    Meta http-equiv属性
    CAC的Debian-8-64bit安装BBR正确打开方式
    CAC的Debian-8-64bit安装BBR正确方式是?
    Mbps Mb M Kb如何换算
    如何解决服务器远程桌面连接成功但重启却操作失效?
  • 原文地址:https://www.cnblogs.com/AlenaNuna/p/10940201.html
Copyright © 2020-2023  润新知