zoukankan      html  css  js  c++  java
  • 普通平衡树Tyvj1728、luogu P3369 (treap)

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

    1. 插入x数

    2. 删除x数(若有多个相同的数,因只删除一个)

    3. 查询x数的排名(若有多个相同的数,因输出最小的排名)

    4. 查询排名为x的数

    5. 求x的前驱(前驱定义为小于x,且最大的数)

    6. 求x的后继(后继定义为大于x,且最小的数)

                 --by 洛谷;

    http://www.lydsy.com/JudgeOnline/problem.php?id=3224



      话说,没时间写题解啊——

      不过,也就是个平衡树的模板题;

        就存下代码吧

      treap哟;

      好像很少见写treap的,但常数还是挺小的orz;

      哎,最近怎么老写模板啊?

      代码如下:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 using namespace std;
      4 #define INF 2147483647
      5 int n;
      6 struct poo
      7 {
      8     int size,value,key,cnt;
      9     int ch[2];
     10 }data[100001];
     11 int tot,root,x;
     12 int  make_data(int );
     13 void insert(int&);
     14 void roll(int&);
     15 int  find(    );
     16 int  rank(    );
     17 void del(int&);
     18 int  las(int );
     19 int  nex(int );
     20 void up(int );
     21 int main()
     22 {
     23     int i,j;
     24     data[0].value=INF;data[0].key=INF;
     25     scanf("%d",&n);
     26     for(i=1;i<=n;i++){
     27         scanf("%d%d",&j,&x);
     28         switch(j){
     29             case 1:insert(root);break;
     30             case 2:   del(root);break;
     31             case 3:  printf("%d
    ",rank(    ));break;
     32             case 4:  printf("%d
    ",find(    ));break;
     33             case 5:  printf("%d
    ", las(root));break;
     34             case 6:  printf("%d
    ", nex(root));break;
     35         }
     36     }
     37 }
     38 int make_data(int value)
     39 {
     40     tot++;
     41     data[tot].cnt++;
     42     data[tot].key=(rand()/2+rand()/2);
     43     data[tot].size=1;
     44     data[tot].value=value;
     45     return tot;
     46 }
     47 void insert(int &now)
     48 {
     49     if(now==0){
     50         now=make_data(x);
     51         return;
     52     }
     53     if(data[now].value==x){
     54         data[now].cnt++;
     55         data[now].size++;
     56     }
     57     else{
     58         int wh=x < data[now].value ? 0 : 1;
     59         insert(data[now].ch[wh]);
     60         if(data[now].key>=data[data[now].ch[wh]].key)
     61             roll(now);
     62     }
     63     up(now);
     64 }
     65 void roll(int &now)
     66 {
     67     int wh=data[data[now].ch[0]].key<data[data[now].ch[1]].key?0:1;
     68     int son=data[now].ch[wh];
     69     data[now].ch[wh]=data[son].ch[wh^1];
     70     data[son].ch[wh^1]=now;
     71     up(now);
     72     now=son;
     73 }
     74 int find()
     75 {
     76     int now=root;
     77     int ls,rs;
     78     ls=data[now].ch[0];rs=data[now].ch[1];
     79     while(x<=data[ls].size||x>data[now].size-data[rs].size){
     80         if(data[ls].size>=x)
     81             now=ls;
     82         else{
     83             x=x+data[rs].size-data[now].size;
     84             now=rs;
     85         }
     86         ls=data[now].ch[0];rs=data[now].ch[1];
     87     }
     88     return data[now].value;
     89 }
     90 int rank()
     91 {
     92     int now=root,ans=0;
     93     int ls=data[now].ch[0],rs=data[now].ch[1];
     94     while(x!=data[now].value&&x!=0)
     95     {
     96         if(x<data[now].value)
     97             now=ls;
     98         else{
     99             ans+=data[now].size-data[rs].size;
    100             now=rs;
    101         }
    102         ls=data[now].ch[0];rs=data[now].ch[1];
    103     }
    104     return ans+data[ls].size+1;
    105 }
    106 void del(int &now)
    107 {
    108     if(data[now].value==x){
    109         if(data[now].cnt==1){
    110             if(data[now].ch[0]*data[now].ch[1]==0){
    111                 now=data[now].ch[1]+data[now].ch[0];
    112                 return ;
    113             }
    114             roll(now);
    115             int wh=data[data[now].ch[0]].value==x?0:1;
    116             del(data[now].ch[wh]);
    117         }
    118         else{
    119             data[now].size--;    data[now].cnt--;
    120         }
    121     }
    122     else{
    123         int wh=data[now].value>x?0:1;
    124         del(data[now].ch[wh]);
    125     }
    126     up(now);
    127 }
    128 int las(int now)
    129 {
    130     int ans=0,an=0;
    131     if(!now)return 0;
    132     if(data[now].value<x){
    133         ans=data[now].value;
    134         an=las(data[now].ch[1]);
    135         ans=an!=0?an:ans;
    136     }
    137     else{
    138         ans=las(data[now].ch[0]);
    139     }
    140     return ans;
    141 }
    142 int nex(int now)
    143 {
    144     int ans=0,an=0;
    145     if(!now)return 0;
    146     if(data[now].value>x){
    147         ans=data[now].value;
    148         an=nex(data[now].ch[0]);
    149         ans=an!=0?an:ans;
    150     }
    151     else{
    152         ans=nex(data[now].ch[1]);
    153     }
    154     return ans;
    155 }
    156 void up(int now)
    157 {
    158     data[now].size=data[data[now].ch[0]].size+data[data[now].ch[1]].size+data[now].cnt;
    159 }
    160 //treap on the 2017.1.21
    161 //10
    162 //1 5
    163 //4 1
    164 //1 6
    165 //1 7
    166 //1 10
    167 //1 3
    168 //1 4
    169 //6 2
    170 //1 8
    171 //5 9
    172 //
    173 //14
    174 //1 5
    175 //1 6
    176 //1 7
    177 //1 10
    178 //1 3
    179 //1 4
    180 //1 8
    181 //3 3
    182 //3 4
    183 //3 5
    184 //3 6
    185 //4 5
    186 //4 6
    187 //4 7

    祝AC哟;

  • 相关阅读:
    Period 计算日期之间的时间差遇到的问题
    Spring cloud jenkins 使用问题笔记jenkins publish over ssh (Exec exit status not zero. Status)
    Linux中scp命令获取远程文件的方法
    HTML5+CSS3从入门到精通 pdf下载
    Oracle RMAN-08137报错处理
    SQL中如何使用EXISTS替代IN
    你撸代码时,会戴耳机吗?
    MySQL必知必会 pdf下载
    SqlServer的sa账号被锁定
    windows系统如何查看端口被占用、杀进程
  • 原文地址:https://www.cnblogs.com/nietzsche-oier/p/6337585.html
Copyright © 2011-2022 走看看