zoukankan      html  css  js  c++  java
  • treap板子(洛谷 P3369 【模板】普通平衡树(Treap/SBT))

    由于有相同的数,每个节点加一个权值表示此数出现的次数

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<ctime>
      4 #include<algorithm>
      5 using namespace std;
      6 #define MAXI 2147483647
      7 //http://blog.csdn.net/h348592532/article/details/52837228随机数
      8 int rand1()
      9 {
     10     static int x=471;
     11     return x=(48271LL*x+1)%2147483647;
     12 }
     13 struct Node
     14 {
     15     Node* ch[2];
     16     int r;//优先级
     17     int v;//value
     18     int size;//维护子树的节点个数
     19     int num;//当前数字出现次数
     20     int cmp(int x) const//要在当前节点的哪个子树去查找,0左1右
     21     {
     22         if(x==v)    return -1;
     23         return v<x;//x<v?0:1
     24     }
     25     void upd()
     26     {
     27         size=num;
     28         if(ch[0]!=NULL)    size+=ch[0]->size;
     29         if(ch[1]!=NULL)    size+=ch[1]->size;
     30     }
     31 }nodes[200100];
     32 int mem,n;
     33 Node* root=NULL;
     34 void rotate(Node* &o,int d)
     35 {
     36     Node* t=o->ch[d^1];o->ch[d^1]=t->ch[d];t->ch[d]=o;
     37     o->upd();t->upd();//o是t子节点,一定要这个顺序upd
     38     o=t;//将当前节点变成旋转完后新的父节点
     39 }
     40 Node* getnode()
     41 {
     42     return &nodes[mem++];
     43 }
     44 void insert(Node* &o,int x)
     45 {
     46     if(o==NULL)
     47     {
     48         o=getnode();o->ch[0]=o->ch[1]=NULL;
     49         o->v=x;o->r=rand1();o->num=1;
     50     }
     51     else
     52     {
     53         if(o->v==x)    ++(o->num);
     54         else
     55         {
     56             int d=o->v < x;//x < o->v?0:1
     57             insert(o->ch[d],x);
     58             if(o->r < o->ch[d]->r)    rotate(o,d^1);//不是 x < o->ch[d]->r
     59         }
     60     }
     61     o->upd();
     62 }
     63 void remove(Node* &o,int x)
     64 {
     65     int d=o->cmp(x);
     66     if(d==-1)
     67     {
     68         if(o->num > 0)
     69         {
     70             --(o->num);
     71         }
     72         if(o->num == 0)
     73         {
     74             if(o->ch[0]==NULL)    o=o->ch[1];
     75             else if(o->ch[1]==NULL)    o=o->ch[0];
     76             else
     77             {
     78                 //int d2= o->ch[0]->r > o->ch[1]->r;//o->ch[0]->r > o->ch[1]->r ? 1:0
     79                 int d2=o->ch[1]->r < o->ch[0]->r;//o->ch[1]->r <= o->ch[0]->r
     80                 rotate(o,d2);
     81                 remove(o->ch[d2],x);
     82                 //左旋则原节点变为新节点的左子节点,右旋相反
     83             }
     84         }
     85     }
     86     else    remove(o->ch[d],x);
     87     if(o!=NULL)    o->upd();
     88 }
     89 bool find(Node* o,int x)
     90 {
     91     int d;
     92     while(o!=NULL)
     93     {
     94         d=o->cmp(x);
     95         if(d==-1)    return 1;
     96         else o=o->ch[d];
     97     }
     98     return 0;
     99 }
    100 int kth(Node* o,int k)
    101 {
    102     if(o==NULL||k<=0||k > o->size)    return 0;
    103     int s= o->ch[0]==NULL ? 0 : o->ch[0]->size;
    104     if(k>s&&k<=s+ o->num)    return o->v;
    105     else if(k<=s)    return kth(o->ch[0],k);
    106     else    return kth(o->ch[1],k-s- o->num);
    107 }
    108 int rk(Node* o,int x)
    109 {
    110     int r=o->ch[0]==NULL ? 0 : o->ch[0]->size;
    111     if(x==o->v)    return r+1;
    112     else    if(x<o->v)    return rk(o->ch[0],x);
    113     else    return r+ o->num +rk(o->ch[1],x);
    114 }
    115 int pre(Node* o,int x)
    116 {
    117     if(o==NULL)    return -MAXI;
    118     int d=o->cmp(x);
    119     if(d<=0)    return pre(o->ch[0],x);
    120     else    return max(o->v,pre(o->ch[1],x));
    121 }
    122 int nxt(Node* o,int x)
    123 {
    124     if(o==NULL)    return MAXI;
    125     int d=o->cmp(x);
    126     if(d!=0)    return nxt(o->ch[1],x);
    127     else    return min(o->v,nxt(o->ch[0],x));
    128 }
    129 int main()
    130 {
    131     int i,o,x;
    132     scanf("%d",&n);
    133     for(i=1;i<=n;i++)
    134     {
    135         scanf("%d%d",&o,&x);
    136         if(o==1)    insert(root,x);
    137         else if(o==2)    remove(root,x);
    138         else if(o==3)    printf("%d
    ",rk(root,x));
    139         else if(o==4)    printf("%d
    ",kth(root,x));
    140         else if(o==5)    printf("%d
    ",pre(root,x));
    141         else printf("%d
    ",nxt(root,x));
    142     }
    143     return 0;
    144 }

    本来想写成相同的数分成多个节点放的,写了一会儿各种细节,炸了

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<ctime>
      4 #include<algorithm>
      5 using namespace std;
      6 struct Node
      7 {
      8     Node* ch[2];
      9     int r;//优先级
     10     int v;//value
     11     int size;//维护子树的节点个数
     12     
     13     int cmp(int x) const//要在当前节点的哪个子树去查找,0左1右
     14     {
     15         if(x==v)    return -1;
     16         return v<x;//x<v?0:1
     17     }
     18     void upd()
     19     {
     20         size=1;
     21         if(ch[0]!=NULL)    size+=ch[0]->size;
     22         if(ch[1]!=NULL)    size+=ch[1]->size;
     23     }
     24 }nodes[200100];
     25 int mem;
     26 void rotate(Node* &o,int d)
     27 {
     28     Node* t=o->ch[d^1];o->ch[d^1]=t->ch[d];t->ch[d]=o;
     29     o->upd();t->upd();
     30     o=t;//将当前节点变成旋转完后新的父节点
     31 }
     32 Node* getnode()
     33 {
     34     return &nodes[mem++];
     35 }
     36 void insert(Node* &o,int x)
     37 {
     38     if(o==NULL)
     39     {
     40         o=getnode();o->ch[0]=o->ch[1]=NULL;
     41         o->v=x;o->r=rand();
     42     }
     43     else
     44     {
     45         //int d=o->cmp(x);不重复
     46         int d=o->v <= x;//x < o->v?0:1
     47         //按照以上左侧的插入方式,相等的会在左子树中插入
     48         insert(o->ch[d],x);
     49         if(o->ch[d]->r > o->r)//不是> x
     50             rotate(o,d^1);
     51     }
     52     o->upd();
     53 }
     54 void remove(Node* &o,int x)
     55 {
     56     int d=o->cmp(x);
     57     if(d==-1)
     58     {
     59         if(o->ch[0]==NULL)    o=o->ch[1];
     60         else if(o->ch[1]==NULL)    o=o->ch[0];
     61         else
     62         {
     63             //int d2= o->ch[0]->r > o->ch[1]->r;//o->ch[0]->r > o->ch[1]->r ? 1:0
     64             int d2=o->ch[1]->r <= o->ch[0]->r; 
     65             rotate(o,d2);
     66             remove(o->ch[d2],x);
     67             //左旋则原节点变为新节点的左子节点,右旋相反
     68         }
     69     }
     70     else    remove(o->ch[d],x);
     71     if(o!=NULL)    o->upd();
     72 }
     73 bool find(Node* o,int x)
     74 {
     75     int d;
     76     while(o!=NULL)
     77     {
     78         d=o->cmp(x);
     79         if(d==-1)    return 1;
     80         else o=o->ch[d];
     81     }
     82     return 0;
     83 }
     84 int kth(Node* o,int k)
     85 {
     86     if(o==NULL||k<=0||k > o->size)    return 0;
     87     int s= o->ch[0]==NULL ? 0 : o->ch[0]->size;
     88     if(k==s+1)    return o->v;
     89     else if(k<=s)    return kth(o->ch[0],k);
     90     else    return kth(o->ch[1],k-s-1);
     91 }
     92 //int rank(Node* o,int x)//不可重复
     93 //{
     94 //    int r= t->ch[0]==NULL ? 0 : t->ch[0]->size;
     95 //    if(x==o->v)    return r+1;
     96 //    else    if(x<o->v)    return rank(o->ch[0],x);
     97 //    else    return r+1+rank(o->ch[1],x);
     98 //}
     99 int rank(Node* o,int x)//支持重复
    100 {
    101     int r=t->ch[0]==NULL ? 0 : t->ch[0]->size;
    102     if(x==o->v)
    103     {
    104         int t=rank(o->ch[
    105     }
    106 }
    107 int pre(Node* o,int x)
    108 {
    109     if(o==NULL)    return -1;
    110     if(x==o->v)    return 
    111     if(x<o->v)    return min(o->v,pre(o->ch[0],
    112 }
    113 int main()
    114 {
    115     srand(time(0));
    116     
    117     return 0;
    118 }
  • 相关阅读:
    log4net 简单使用教程(配置)
    C#WinForm 国际化的简单实现,多语言实现
    EF Power Tool 参数错误 HRESULT:0x80070057 (E_INVALIDARG)) 解决办法
    如何用委托与事件实现winfrom窗体之间值传递
    VS2010自带的Dotfuscator 5注册
    WinForm 实现主程序(exe)与其关联类库(*.dll)分开存放
    POJ_3211 Washing Clothes (01背包)
    POJ_3624 Charm Bracelet ( 01背包 )
    集训队内部测试赛(2012.01.02)
    HDU_1011 Starship Troopers && HDU_1561 The more, The Better (树型dp)
  • 原文地址:https://www.cnblogs.com/hehe54321/p/7856669.html
Copyright © 2011-2022 走看看