各种平衡树板子

Splay

  1 #include <cstdio>
  2 #include <iostream>
  3 using namespace std;
  4 const int maxn=1e5+5,inf=0x3f3f3f3f;
  5 int siz[maxn],fa[maxn],ch[maxn][2],rep[maxn],vl[maxn];
  6 int n,tot;
  7
  8 inline int ids(int x) {return ch[fa[x]][0]==x?0:1;}
  9
 10 inline void update(int x) {siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+rep[x];}
 11
 12 inline void connect(int x,int f,int fs) {fa[x]=f;ch[f][fs]=x;}
 13
 14 inline void rotate(const int &x)
 15 {
 16     int f=fa[x],ff=fa[fa[x]];
 17     int s1=ids(x),s2=ids(f);
 18     connect(ch[x][s1^1],f,s1);connect(f,x,s1^1);connect(x,ff,s2);
 19     update(f);update(x);
 20 }
 21
 22 inline void splay(int x,int to)
 23 {
 24     while(fa[x]!=to)
 25     {
 26         if(fa[fa[x]]==to) rotate(x);
 27         else if(ids(fa[x])==ids(x)) rotate(fa[x]),rotate(x);
 28         else rotate(x),rotate(x);
 29     }
 30 }
 31
 32 inline int cre(const int &val,const int &f) {fa[++n]=f;vl[n]=val;siz[n]=rep[n]=1;return n;}
 33
 34 int find(int val)
 35 {
 36     int now=ch[0][0],nxt;
 37     while(1)
 38     {
 39         if(vl[now]==val){
 40             splay(now,0);
 41             return now;
 42         }
 43         nxt=val<vl[now]?0:1;
 44         if(!ch[now][nxt]) return 0;
 45         now=ch[now][nxt];
 46     }
 47 }
 48
 49 void insert(int val)
 50 {
 51     tot++;
 52     if(!ch[0][0]) {ch[0][0]=cre(val,0);return;}
 53     int now=ch[0][0],nxt;
 54     while(1)
 55     {
 56         siz[now]++;
 57         if(val==vl[now]){
 58             rep[now]++;splay(now,0);return;
 59         }
 60         nxt=val<vl[now]?0:1;
 61         if(!ch[now][nxt])
 62         {
 63             ch[now][nxt]=cre(val,now);
 64             splay(ch[now][nxt],0);
 65             return;
 66         }
 67         now=ch[now][nxt];
 68     }
 69 }
 70
 71 inline int lowe(int x)
 72 {
 73     int now=ch[0][0],ans=-inf;
 74     while(now){
 75         if(vl[now]<x&&vl[now]>ans) ans=vl[now];
 76         now=ch[now][x>vl[now]?1:0];
 77     }
 78     return ans;
 79 }
 80
 81 inline int uppe(int x)
 82 {
 83     int now=ch[0][0],ans=inf;
 84     while(now){
 85         if(vl[now]>x&&vl[now]<ans) ans=vl[now];
 86         now=ch[now][x<vl[now]?0:1];
 87     }
 88     return ans;
 89 }
 90
 91 void delt(int x)
 92 {
 93     tot--;
 94     int dl=find(x);
 95     if(!dl) return;
 96     if(rep[dl]>1) {siz[dl]--;rep[dl]--;return;}
 97     if(!ch[dl][0]) {connect(ch[dl][1],0,0);return;}
 98     if(!ch[dl][1]) {connect(ch[dl][0],0,0);return;}
 99     int px=ch[dl][0];
100     while(ch[px][1]) px=ch[px][1];
101     splay(px,dl);
102     connect(ch[dl][1],px,1);connect(px,0,0);
103     update(px);
104 }
105
106 int rk(int val)
107 {
108     int ans=0,now=ch[0][0];
109     while(now)
110     {
111         if(vl[now]==val){
112             ans+=siz[ch[now][0]]+1;break;
113         }
114         if(val<vl[now]) now=ch[now][0];
115         else ans+=siz[ch[now][0]]+rep[now],now=ch[now][1];
116     }
117     splay(now,0);
118     return ans;
119 }
120
121 int rrk(int x)
122 {
123     if(x>tot) return -inf;
124     int now=ch[0][0],tmp;
125     while(now)
126     {
127         tmp=rep[now]+siz[ch[now][0]];
128         if(siz[ch[now][0]]<x&&x<=tmp) break;
129         if(x<tmp) now=ch[now][0];
130         else x-=tmp,now=ch[now][1];
131     }
132     splay(now,0);
133     return vl[now];
134 }
135
136 int main()
137 {
138     int t,opt,x;
139     scanf("%d",&t);
140     for(int i=1;i<=t;i++)
141     {
142         scanf("%d%d",&opt,&x);
143         switch(opt)
144         {
145             case 1: insert(x);break;
146             case 2: delt(x);break;
147             case 3: printf("%d\n",rk(x));break;
148             case 4: printf("%d\n",rrk(x));break;
149             case 5: printf("%d\n",lowe(x));break;
150             case 6: printf("%d\n",uppe(x));break;
151             default: break;
152         }
153     }
154     return 0;
155 }

Fhq-treap

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <ctime>
  4 #include <cstdlib>
  5 using namespace std;
  6 const int maxn=1e5+5;
  7 struct Fhq_treep_Node
  8 {
  9     int val,siz,ch[2],rnd;
 10 }tr[maxn];
 11 int rt,r1,r2,r3,utot;
 12
 13 inline void update(const int &u) {tr[u].siz=tr[tr[u].ch[0]].siz+tr[tr[u].ch[1]].siz+1;}
 14 inline int newnode(const int &val) {tr[++utot].val=val;tr[utot].siz=1;tr[utot].rnd=rand();return utot;}
 15
 16 void split(int u,int val,int &a,int &b)
 17 {
 18     if(!u) {a=b=0;return;}
 19     if(tr[u].val<=val) a=u,split(tr[a].ch[1],val,tr[a].ch[1],b);
 20     else b=u,split(tr[b].ch[0],val,a,tr[b].ch[0]);
 21     update(u);
 22 }
 23
 24 int merge(int a,int b)
 25 {
 26     if(!a||!b) return a+b;
 27     if(tr[a].rnd<tr[b].rnd){
 28         tr[a].ch[1]=merge(tr[a].ch[1],b);
 29         update(a);return a;
 30     }
 31     else{
 32         tr[b].ch[0]=merge(a,tr[b].ch[0]);
 33         update(b);return b;
 34     }
 35 }
 36
 37 void insert(int val)
 38 {
 39     split(rt,val,r1,r2);
 40     rt=merge(r1,merge(newnode(val),r2));
 41 }
 42
 43 void delt(int val)
 44 {
 45     split(rt,val,r1,r3);
 46     split(r1,val-1,r1,r2);
 47     r2=merge(tr[r2].ch[0],tr[r2].ch[1]);
 48     rt=merge(merge(r1,r2),r3);
 49 }
 50
 51 int rnk(int val)
 52 {
 53     split(rt,val-1,r1,r2);
 54     int ans=tr[r1].siz+1;
 55     rt=merge(r1,r2);
 56     return ans;
 57 }
 58
 59 int kth(int u,int k)
 60 {
 61     while(1)
 62     {
 63         if(tr[tr[u].ch[0]].siz>=k) u=tr[u].ch[0];
 64         else if(k>tr[tr[u].ch[0]].siz+1) k=k-tr[tr[u].ch[0]].siz-1,u=tr[u].ch[1];
 65         else return u;
 66     }
 67 }
 68
 69 void lower(int val)
 70 {
 71     split(rt,val-1,r1,r2);
 72     printf("%d\n",tr[kth(r1,tr[r1].siz)].val);
 73     rt=merge(r1,r2);
 74 }
 75
 76 void upper(int val)
 77 {
 78     split(rt,val,r1,r2);
 79     printf("%d\n",tr[kth(r2,1)].val);
 80     rt=merge(r1,r2);
 81 }
 82
 83 int main()
 84 {
 85     srand(time(0));
 86     int opt,x,t;
 87     scanf("%d",&t);
 88     while(t--)
 89     {
 90         scanf("%d%d",&opt,&x);
 91         switch(opt)
 92         {
 93             case 1:insert(x);break;
 94             case 2:delt(x);break;
 95             case 3:printf("%d\n",rnk(x));break;
 96             case 4:printf("%d\n",tr[kth(rt,x)].val);break;
 97             case 5:lower(x);break;
 98             case 6:upper(x);break;
 99         }
100     }
101     return 0;
102 }

原文地址:https://www.cnblogs.com/gxm123/p/12422416.html

时间: 2024-11-19 07:19:16

各种平衡树板子的相关文章

几个平衡树板子

Treap,替罪羊树,splay.跑得不慢,代码在不影响版面的前提下基本已经缩到极限了,不知道还能不能更短. 其实我还会写AVL树,只不过太长懒得写了.反正Treap和替罪羊树跑得也挺快,用用这俩就够了. 话说Treap和替罪羊树都是重量平衡树来着--这倒是方便我了,不过写动态标号的时候到底该写哪个呢--这是个问题-- Treap(普通平衡树): 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4

[bzoj] 3224 Tyvj 1728 普通平衡树 || 平衡树板子题

#!/bin/bash g++ make.cpp -o make -Wall g++ 1.cpp -o ac -Wall g++ sb.cpp -o sb -Wall while true; do ./make > 1.in ./ac < 1.in > 1.out ./sb < 1.in > sb.out if diff 1.out sb.out; then printf "AC!" else exit fi done 原文地址:https://www.c

替罪羊树(重量平衡树)总结及板子

没事干写个板子来玩一玩...平衡树的板子,上一篇写的 splay 的题解,这一篇来搞点别的.其实就我自己来说,并不太喜欢 splay ,各种旋转什么的,扭扭捏捏一点都不爽,那怎么办咧,于是学了这么个东西---替罪羊树,不平衡就重构嘛,简单粗暴,写起来也方便. 替罪羊树的主要思想就是将不平衡的树压成一个序列,然后暴力重构成一颗平衡的树. 这里的平衡指的是:对于某个 0.5<=alpha<=1 满足 size( lson(x) )<=alpha*size(x) 并且 size( rson(x

[补档][Tyvj 1728]普通平衡树

题目 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入x数 2. 删除x数(若有多个相同的数,因只删除一个) 3. 查询x数的排名(若有多个相同的数,因输出最小的排名) 4. 查询排名为x的数 5. 求x的前驱(前驱定义为小于x,且最大的数) 6. 求x的后继(后继定义为大于x,且最小的数) INPUT 第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6) OUTPUT 对于操作3,4,5,6每行输出一个

种下一棵树:有旋Treap

第一个平衡树板子,有旋Treap.用随机函数规定一个堆,维护点权的同时维护堆的性质,可以有效地避免退化成链.按我的理解,建立一棵二叉排序树,树的形态会和给出节点的顺序有关.按照出题人很机智定理,数据肯定不会太容易操作,这时候就需要我们自行调整"数据顺序",平衡树应运而生. 这个板子涵盖的操作有左旋.右旋(维护堆性质).添加节点.删除节点(建树相关).查找第x个元素.查找元素排名.查找前驱.查找后继这8种操作.改变树本身的操作都是取地址传参的,询问操作则都是简单传参.原理不是太难理解,应

Codeforces 420D. Cup Trick

平衡树板子题,虽然似乎有着高妙的树状数组搞法,但本着用用pb_ds这种bug库的存在,就没管了orz #include <cstdio> #include <ext/pb_ds/assoc_container.hpp> #include <algorithm> const int N = 2e6 + 100; int n, m; __gnu_pbds::tree<int, __gnu_pbds::null_type, std::less<int>, _

SPLAY or SPALY ?

写在前面: 由我们可爱的Daniel Sleator和Robert Tarjan提出的一种数据结构,平衡树的一种,本质是二叉树. 至于到底是splay还是spaly,我认为可能splay更对一些 毕竟splay是有实意的单词,更有可能一点.而且WIKI百科页也是splay 以下是本人学习splay的一点过程,请多指教喽 SPLAY 那么我在这里复习整理一下spaly的代码相关吧 例题:http://www.lydsy.com/JudgeOnline/problem.php?id=3224 参考博

3224: Tyvj 1728 普通平衡树(新板子)

3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 17048  Solved: 7429[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. 求x的前驱(前驱定义为

P3391 【模板】文艺平衡树(Splay)新板子

P3391 [模板]文艺平衡树(Splay) 题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 输入输出格式 输入格式: 第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2, \cdots n-1,n)(1,2,?n−1,n) m表示翻转操作次数 接下来m行每行两个数 [l,r][l,