题目描述
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
-
插入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 ",getk(Root,x)); 116 else if (opt==4) printf("%d ",getkth(Root,x)); 117 else if (opt==5) ans = 0,getpre(Root,x),printf("%d ",t[ans].val); 118 else ans = 0,getsuc(Root,x),printf("%d ",t[ans].val); 119 } 120 return 0; 121 }
更新后的treap
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<algorithm> 3 #include<ctime> 4 5 using namespace std; 6 7 #define lson t[k].l 8 #define rson t[k].r 9 const int N = 200010; 10 11 struct Data{ 12 int l,r,val,key,siz,cnt; 13 }t[N]; 14 int Root,tn,ans; 15 16 inline char nc() { 17 static char buf[100000],*p1 = buf,*p2 = buf; 18 return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF :*p1++; 19 } 20 inline int read() { 21 int x = 0,f = 1;char ch=nc(); 22 for (; ch<'0'||ch>'9'; ch = nc()) 23 if (ch == '-') f = -1; 24 for (; ch>='0'&&ch<='9'; ch = nc()) 25 x = x*10+ch-'0'; 26 return x * f; 27 } 28 29 inline void pushup(int k) { 30 t[k].siz = t[lson].siz + t[rson].siz + t[k].cnt; 31 } 32 inline void leftturn(int &k) { 33 int a = rson; 34 rson = t[a].l; 35 t[a].l = k; 36 t[a].siz = t[k].siz; 37 pushup(k); 38 k = a; 39 } 40 inline void rightturn(int &k) { 41 int a = lson; 42 lson = t[a].r; 43 t[a].r = k; 44 t[a].siz = t[k].siz; 45 pushup(k); 46 k = a; 47 } 48 void Insert(int &k,int x) { 49 if (k==0) { 50 tn++;k = tn; 51 t[k].siz = t[k].cnt = 1; 52 t[k].val = x;t[k].key = rand(); 53 return ; 54 } 55 t[k].siz++; 56 if (t[k].val==x) t[k].cnt ++; 57 else if (x > t[k].val) { 58 Insert(rson,x); 59 if (t[rson].key < t[k].key) leftturn(k); 60 } 61 else { 62 Insert(lson,x); 63 if (t[lson].key < t[k].key) rightturn(k); 64 } 65 } 66 void Delete(int &k,int x) { 67 if (k==0) return ; 68 if (t[k].val==x) { 69 if (t[k].cnt > 1) { 70 t[k].cnt--;t[k].siz--;return ; 71 } 72 if (lson * rson == 0) k = lson + rson; 73 else if (t[lson].key < t[rson].key) { 74 rightturn(k);Delete(k,x); 75 } 76 else { 77 leftturn(k);Delete(k,x); 78 } 79 } 80 else if (x > t[k].val) { 81 t[k].siz--;Delete(rson,x); 82 } 83 else { 84 t[k].siz--;Delete(lson,x); 85 } 86 } 87 int getk(int k,int x) { 88 if (k==0) return 0; 89 if (t[k].val==x) return t[lson].siz + 1; 90 else if (x > t[k].val) 91 return t[lson].siz + t[k].cnt + getk(rson,x); 92 else return getk(lson,x); 93 } 94 int getkth(int k,int x) { 95 if (k==0) return 0; 96 if (x <= t[lson].siz) return getkth(lson,x); 97 else if (x > t[lson].siz + t[k].cnt) 98 return getkth(rson,x-t[lson].siz-t[k].cnt); 99 else return t[k].val; 100 } 101 void getpre(int k,int x) { 102 if (k==0) return ; 103 if (t[k].val < x) ans = k,getpre(rson,x); 104 else getpre(lson,x); 105 } 106 void getsuc(int k,int x) { 107 if (k==0) return ; 108 if (t[k].val > x) ans = k,getsuc(lson,x); 109 else getsuc(rson,x); 110 } 111 112 int main() { 113 int n = read(); 114 while (n--){ 115 int opt = read(),x = read(); 116 if (opt==1) Insert(Root,x); 117 else if (opt==2) Delete(Root,x); 118 else if (opt==3) printf("%d ",getk(Root,x)); 119 else if (opt==4) printf("%d ",getkth(Root,x)); 120 else if (opt==5) ans = 0,getpre(Root,x),printf("%d ",t[ans].val); 121 else ans = 0,getsuc(Root,x),printf("%d ",t[ans].val); 122 } 123 return 0; 124 }