P3369 模板普通平衡树 Treap
Posted HWIM
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3369 模板普通平衡树 Treap相关的知识,希望对你有一定的参考价值。
题目描述
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
-
插入x数
-
删除x数(若有多个相同的数,因只删除一个)
-
查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
-
查询排名为x的数
-
求x的前驱(前驱定义为小于x,且最大的数)
- 求x的后继(后继定义为大于x,且最小的数)
输入输出格式
输入格式:
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号( 1 \leq opt \leq 61≤opt≤6 )
输出格式:
对于操作3,4,5,6每行输出一个数,表示对应答案
输入输出样例
输入样例#1: 复制
10 1 106465 4 1 1 317721 1 460929 1 644985 1 84185 1 89851 6 81968 1 492737 5 493598
输出样例#1: 复制
106465 84185 492737
说明
时空限制:1000ms,128M
1.n的数据范围: n \leq 100000n≤100000
2.每个数的数据范围: [-{10}^7, {10}^7][−107,107]
来源:Tyvj1728 原名:普通平衡树
在此鸣谢
code
treap 真是个好东西。。
1 #include<cstdio> 2 #include<algorithm> 3 #include<ctime> 4 using namespace std; 5 6 const int N = 200010; 7 8 struct Data{ 9 int l,r,val,key,siz,cnt; 10 }t[N]; 11 int Root,tn,ans; 12 13 inline char nc() { 14 static char buf[100000],*p1 = buf,*p2 = buf; 15 return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF :*p1++; 16 } 17 inline int read() { 18 int x = 0,f = 1;char ch=nc(); 19 for (; ch<‘0‘||ch>‘9‘; ch = nc()) 20 if (ch == ‘-‘) f = -1; 21 for (; ch>=‘0‘&&ch<=‘9‘; ch = nc()) 22 x = x*10+ch-‘0‘; 23 return x * f; 24 } 25 26 inline void pushup(int x) { 27 t[x].siz = t[t[x].l].siz + t[t[x].r].siz + t[x].cnt; 28 } 29 inline void leftturn(int &k) { 30 int a = t[k].r; 31 t[k].r = t[a].l; 32 t[a].l = k; 33 t[a].siz = t[k].siz; 34 pushup(k); 35 k = a; 36 } 37 inline void rightturn(int &k) { 38 int a = t[k].l; 39 t[k].l = t[a].r; 40 t[a].r = k; 41 t[a].siz = t[k].siz; 42 pushup(k); 43 k = a; 44 } 45 void Insert(int &k,int x) { 46 if (k==0) { 47 tn++;k = tn; 48 t[k].siz = t[k].cnt = 1; 49 t[k].val = x;t[k].key = rand(); 50 return ; 51 } 52 t[k].siz++; 53 if (t[k].val==x) t[k].cnt ++; 54 else if (x > t[k].val) { 55 Insert(t[k].r,x); 56 if (t[t[k].r].key < t[k].key) leftturn(k); 57 } 58 else { 59 Insert(t[k].l,x); 60 if (t[t[k].l].key < t[k].key) rightturn(k); 61 } 62 } 63 void Delete(int &k,int x) { 64 if (k==0) return ; 65 if (t[k].val==x) { 66 if (t[k].cnt > 1) { 67 t[k].cnt--;t[k].siz--;return ; 68 } 69 if (t[k].l * t[k].r == 0) k = t[k].l + t[k].r; 70 else if (t[t[k].l].key < t[t[k].r].key) { 71 rightturn(k);Delete(k,x); 72 } 73 else { 74 leftturn(k);Delete(k,x); 75 } 76 } 77 else if (x > t[k].val) { 78 t[k].siz--;Delete(t[k].r,x); 79 } 80 else { 81 t[k].siz--;Delete(t[k].l,x); 82 } 83 } 84 int getk(int k,int x) { 85 if (k==0) return 0; 86 if (t[k].val==x) return t[t[k].l].siz + 1; 87 else if (x > t[k].val) 88 return t[t[k].l].siz + t[k].cnt + getk(t[k].r,x); 89 else return getk(t[k].l,x); 90 } 91 int getkth(int k,int x) { 92 if (k==0) return 0; 93 if (x <= t[t[k].l].siz) return getkth(t[k].l,x); 94 else if (x > t[t[k].l].siz + t[k].cnt) 95 return getkth(t[k].r,x-t[t[k].l].siz-t[k].cnt); 96 else return t[k].val; 97 } 98 void getpre(int k,int x) { 99 if (k==0) return ; 100 if (t[k].val < x) ans = k,getpre(t[k].r,x); 101 else getpre(t[k].l,x); 102 } 103 void getsuc(int k,int x) { 104 if (k==0) return ; 105 if (t[k].val > x) ans = k,getsuc(t[k].l,x); 106 else getsuc(t[k].r,x); 107 } 108 109 int main() { 110 int n = read(); 111 while (n--){ 112 int opt = read(),x = read(); 113 if (opt==1) Insert(Root,x); 114 else if (opt==2) Delete(Root,x); 115 else if (opt==3) printf("%d\n",getk(Root,x)); 116 else if (opt==4) printf("%d\n",getkth(Root,x)); 117 else if (opt==5) ans = 0,getpre(Root,x),printf("%d\n",t[ans].val); 118 else ans = 0,getsuc(Root,x),printf("%d\n",t[ans].val); 119 } 120 return 0; 121 }
以上是关于P3369 模板普通平衡树 Treap的主要内容,如果未能解决你的问题,请参考以下文章
红黑树 ------ luogu P3369 模板普通平衡树(Treap/SBT)
替罪羊树 ------ luogu P3369 模板普通平衡树(Treap/SBT)