永利网上娱乐假设今日而讲话的treap就是平等栽动态平衡的点子。而今天一旦谈的treap就是千篇一律栽动态平衡的法门。

这次咱们来说话同样言Treap(splay以后重新还)

这次咱们来言同样叙Treap(splay以后又另行)

平衡树是一律栽排序二叉树(或二叉搜索树),所以排序二叉树可以长足地认清两独价值的大大小小,当然操作必然不止那么多(不然我们尚模拟啊)。

平衡树是相同种排序二叉树(或二叉搜索树),所以排序二叉树可以很快地认清两个价的大大小小,当然操作必然不止那么基本上(不然我们还套啊)。

若是平衡造就于排序二叉树的根底及主要是长了一个优化:就是可观比较平衡,并得以动态平衡。

要平衡造就于排序二叉树的根基及着重是充实了一个优化:就是莫大比较平衡,并得以动态平衡。

一旦今日如果摆的treap就是同等种动态平衡的方式。

只要今天如谈的treap就是千篇一律栽动态平衡的点子。

首先说声抱歉,因为没有那基本上之年华,所以无法将左旋和右侧旋两栽操作实际的云,但是可以扣押刘汝佳的蓝书,讲得还是甚清楚的。

率先说声抱歉,因为没那基本上之时刻,所以无法拿左旋和右旋两种植操作实际的言语,但是可看刘汝佳的蓝书,讲得还是雅清楚的。

现启幕。

今天启幕。

treap用的凡平等种植于玄学的不二法门,就是以各国一个触及还附上一个任意值,然后以堆的性,不管大小根堆都是相同的,所以我们各加入一个值,就利用上浮操作进行盘,保持堆的性能,且非转排序二叉树的性质。

treap用的是一模一样种比较玄学的方式,就是将各个一个碰还附上一个即兴值,然后以堆的特性,不管大小根堆都是同样的,所以我们各加入一个值,就用上浮操作进行盘,保持堆的特性,且不更改排序二叉树的属性。

操作十分好掌握,就是每次insert时进行判定即便推行了,若未满足,则高达泛。

操作十分好掌握,就是每次insert时进行判定即便推行了,若未满足,则达到泛。

切实的排序二叉树的操作,我就是不再赘言了,如果要学,可以扣押刘汝佳的天蓝书(感觉当跟刘汝佳打广告)。

切切实实的排序二叉树的操作,我就算不再赘述了,如果要学,可以拘留刘汝佳的蔚蓝书(感觉当与刘汝佳打广告)。

脚送及代码。

下送上代码。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<ctime>
  6 using namespace std;
  7 int n,root,size,ans;
  8 struct P{
  9     int l,r,sz,key,rd,re;//re为重复次数,key为加入权值
 10 }t[1000005];
 11 void update(int k)
 12 {
 13     t[k].sz=t[t[k].l].sz+t[t[k].r].sz+t[k].re;
 14 }
 15 void left(int &k)//右旋
 16 {
 17     int y=t[k].r;
 18     t[k].r=t[y].l;
 19     t[y].l=k;
 20     t[y].sz=t[k].sz;
 21     update(k);
 22     k=y;
 23 }
 24 void right(int &k)//左旋
 25 {
 26     int y=t[k].l;
 27     t[k].l=t[y].r;
 28     t[y].r=k;
 29     t[y].sz=t[k].sz;
 30     update(k);
 31     k=y;
 32 }
 33 void init(int &k,int x)//加入操作
 34 {
 35     if(k==0)
 36     {
 37         size++;
 38         k=size;
 39         t[k].sz=1;
 40         t[k].re=1;
 41         t[k].key=x;
 42         t[k].rd=rand();
 43         return;
 44     }
 45     t[k].sz++;
 46     if(t[k].key==x)  t[k].re++;
 47     else{
 48         if(x>t[k].key)
 49         {
 50             init(t[k].r,x);
 51             if(t[t[k].r].rd<t[k].rd)   left(k);//这里和下面都是判断是不是满足堆的性质
 52         }
 53         if(x<t[k].key)
 54         {
 55             init(t[k].l,x);
 56             if(t[t[k].l].rd<t[k].rd)   right(k);
 57         }
 58     }
 59 } 
 60 void del(int &k,int x)
 61 {
 62     if(k==0)  return;
 63     if(t[k].key==x)
 64     {
 65         if(t[k].re>1)
 66         {
 67             t[k].re--;
 68             t[k].sz--;
 69             return;
 70         }
 71         if(t[k].l*t[k].r==0)  k=t[k].l+t[k].r;//k代表指针的移动,所以移动到了左或右儿子
 72         else
 73         {
 74             if(t[t[k].l].rd<t[t[k].r].rd){
 75                 right(k);
 76                 del(k,x);
 77             }
 78             else{
 79                 left(k);
 80                 del(k,x);
 81             }
 82         }
 83     }
 84     else{
 85         if(x>t[k].key)
 86         {
 87             t[k].sz--;
 88             del(t[k].r,x);
 89         }
 90         else{
 91             t[k].sz--;
 92             del(t[k].l,x);
 93         }
 94     }
 95 }
 96 int rank1(int k,int x)//找x的排名
 97 {
 98     if(k==0)  return 0;
 99     if(t[k].key==x)  return t[t[k].l].sz+1;
100     if(x>t[k].key)   return t[t[k].l].sz+rank1(t[k].r,x)+t[k].re;
101     if(x<=t[k].key)  return    rank1(t[k].l,x);
102 }
103 int rank2(int k,int x)//找排名为x的数
104 {
105     if(k==0)  return 0;
106     else if(x<=t[t[k].l].sz)    return rank2(t[k].l,x);
107     else if(x>t[t[k].l].sz+t[k].re)  return rank2(t[k].r,x-t[t[k].l].sz-t[k].re);
108     else  return  t[k].key; 
109 }
110 void pre(int k,int x)//找前驱
111 {
112     if(k==0)  return;
113     if(t[k].key<x)
114     {
115          ans=k;
116          pre(t[k].r,x);
117     }
118     else pre(t[k].l,x);
119 }
120 void nxt(int k,int x)//找后继
121 {
122     if(k==0)  return;
123     if(t[k].key>x)
124     {
125         ans=k;
126         nxt(t[k].l,x);
127     }
128     else nxt(t[k].r,x);
129 }
130 int main()
131 {
132     srand(time(0));
133     scanf("%d",&n);
134     for(int i=1;i<=n;i++)
135     {
136         int num,x;
137         scanf("%d%d",&num,&x);
138         if(num==1)  init(root,x);
139         if(num==2)  del(root,x);
140         if(num==3)  printf("%d\n",rank1(root,x));
141         if(num==4)  printf("%d\n",rank2(root,x));
142         if(num==5)
143         {
144             pre(root,x);
145             printf("%d\n",t[ans].key);
146         }
147         if(num==6)
148         {
149             nxt(root,x);
150             printf("%d\n",t[ans].key);
151         }
152     }
153     return 0;
154 }
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<ctime>
  6 using namespace std;
  7 int n,root,size,ans;
  8 struct P{
  9     int l,r,sz,key,rd,re;//re为重复次数,key为加入权值
 10 }t[1000005];
 11 void update(int k)
 12 {
 13     t[k].sz=t[t[k].l].sz+t[t[k].r].sz+t[k].re;
 14 }
 15 void left(int &k)//右旋
 16 {
 17     int y=t[k].r;
 18     t[k].r=t[y].l;
 19     t[y].l=k;
 20     t[y].sz=t[k].sz;
 21     update(k);
 22     k=y;
 23 }
 24 void right(int &k)//左旋
 25 {
 26     int y=t[k].l;
 27     t[k].l=t[y].r;
 28     t[y].r=k;
 29     t[y].sz=t[k].sz;
 30     update(k);
 31     k=y;
 32 }
 33 void init(int &k,int x)//加入操作
 34 {
 35     if(k==0)
 36     {
 37         size++;
 38         k=size;
 39         t[k].sz=1;
 40         t[k].re=1;
 41         t[k].key=x;
 42         t[k].rd=rand();
 43         return;
 44     }
 45     t[k].sz++;
 46     if(t[k].key==x)  t[k].re++;
 47     else{
 48         if(x>t[k].key)
 49         {
 50             init(t[k].r,x);
 51             if(t[t[k].r].rd<t[k].rd)   left(k);//这里和下面都是判断是不是满足堆的性质
 52         }
 53         if(x<t[k].key)
 54         {
 55             init(t[k].l,x);
 56             if(t[t[k].l].rd<t[k].rd)   right(k);
 57         }
 58     }
 59 } 
 60 void del(int &k,int x)
 61 {
 62     if(k==0)  return;
 63     if(t[k].key==x)
 64     {
 65         if(t[k].re>1)
 66         {
 67             t[k].re--;
 68             t[k].sz--;
 69             return;
 70         }
 71         if(t[k].l*t[k].r==0)  k=t[k].l+t[k].r;//k代表指针的移动,所以移动到了左或右儿子
 72         else
 73         {
 74             if(t[t[k].l].rd<t[t[k].r].rd){
 75                 right(k);
 76                 del(k,x);
 77             }
 78             else{
 79                 left(k);
 80                 del(k,x);
 81             }
 82         }
 83     }
 84     else{
 85         if(x>t[k].key)
 86         {
 87             t[k].sz--;
 88             del(t[k].r,x);
 89         }
 90         else{
 91             t[k].sz--;
 92             del(t[k].l,x);
 93         }
 94     }
 95 }
 96 int rank1(int k,int x)//找x的排名
 97 {
 98     if(k==0)  return 0;
 99     if(t[k].key==x)  return t[t[k].l].sz+1;
100     if(x>t[k].key)   return t[t[k].l].sz+rank1(t[k].r,x)+t[k].re;
101     if(x<=t[k].key)  return    rank1(t[k].l,x);
102 }
103 int rank2(int k,int x)//找排名为x的数
104 {
105     if(k==0)  return 0;
106     else if(x<=t[t[k].l].sz)    return rank2(t[k].l,x);
107     else if(x>t[t[k].l].sz+t[k].re)  return rank2(t[k].r,x-t[t[k].l].sz-t[k].re);
108     else  return  t[k].key; 
109 }
110 void pre(int k,int x)//找前驱
111 {
112     if(k==0)  return;
113     if(t[k].key<x)
114     {
115          ans=k;
116          pre(t[k].r,x);
117     }
118     else pre(t[k].l,x);
119 }
120 void nxt(int k,int x)//找后继
121 {
122     if(k==0)  return;
123     if(t[k].key>x)
124     {
125         ans=k;
126         nxt(t[k].l,x);
127     }
128     else nxt(t[k].r,x);
129 }
130 int main()
131 {
132     srand(time(0));
133     scanf("%d",&n);
134     for(int i=1;i<=n;i++)
135     {
136         int num,x;
137         scanf("%d%d",&num,&x);
138         if(num==1)  init(root,x);
139         if(num==2)  del(root,x);
140         if(num==3)  printf("%d\n",rank1(root,x));
141         if(num==4)  printf("%d\n",rank2(root,x));
142         if(num==5)
143         {
144             pre(root,x);
145             printf("%d\n",t[ans].key);
146         }
147         if(num==6)
148         {
149             nxt(root,x);
150             printf("%d\n",t[ans].key);
151         }
152     }
153     return 0;
154 }

模板题:https://www.luogu.org/problemnew/show/P3369

模板题:https://www.luogu.org/problemnew/show/P3369

多谢大家之目。

谢谢大家之观望。

假设发生不妥之远在,请大家指出。

假使发不妥之处在,请大家指出。

相关文章