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\n",rk(root,x));
139         else if(o==4)    printf("%d\n",kth(root,x));
140         else if(o==5)    printf("%d\n",pre(root,x));
141         else printf("%d\n",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 }
posted @ 2017-11-18 14:43  hehe_54321  阅读(254)  评论(0编辑  收藏  举报
AmazingCounters.com