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的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
Input
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
Output
对于操作3,4,5,6每行输出一个数,表示对应答案
Sample Input
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Sample Output
106465
84185
492737
84185
492737
HINT
1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]
code
2018-07-01
1 #include<cstdio> 2 #include<cctype> 3 4 const int N = 1000100; 5 6 int siz[N],ch[N][2],fa[N],cnt[N],data[N]; 7 int Root,tn; 8 9 #define ls ch[p][0] 10 #define rs ch[p][1] 11 12 int son(int x) { 13 return x==ch[fa[x]][1]; 14 } 15 void pushup(int p) { 16 siz[p] = siz[ls] + siz[rs] + cnt[p]; 17 } 18 void rotate(int x) { 19 int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b]; 20 if (z) ch[z][c] = x;else Root = x;fa[x] = z; 21 ch[x][!b] = y;fa[y] = x; 22 ch[y][b] = a;if (a) fa[a] = y; 23 pushup(y),pushup(x); 24 } 25 void splay(int x,int rt) { 26 while (fa[x] != rt) { 27 int y = fa[x],z = fa[y]; 28 if (z==rt) rotate(x); 29 else { 30 if (son(x)==son(y)) rotate(y),rotate(x); 31 else rotate(x),rotate(x); 32 } 33 } 34 } 35 int getrnk(int x) { 36 int p = Root,ans = 0; 37 while (true) { 38 if (!p) return ans + 1; 39 if (x == data[p]) {ans += siz[ls];splay(p,0);return ans+1;} 40 if (x < data[p]) p = ls; 41 else { 42 ans += siz[ls] + cnt[p]; 43 p = rs; 44 } 45 } 46 } 47 int getkth(int k) { 48 int p = Root; 49 while (true) { 50 if (siz[ls] < k && k <= siz[ls] + cnt[p]) return data[p]; 51 if (k <= siz[ls]) p = ls; 52 else { 53 k -= siz[ls] + cnt[p]; 54 p = rs; 55 } 56 } 57 } 58 int Newnode(int pa,int d) { 59 ++tn;siz[tn] = cnt[tn] = 1;ch[tn][1] = ch[tn][0] = 0; 60 data[tn] = d;fa[tn] = pa; 61 return tn; 62 } 63 void Insert(int x) { 64 if (!Root) {Root = Newnode(0,x);return ;} 65 int p = Root,pa = 0; 66 while (true) { 67 if (data[p]==x) { 68 cnt[p] ++;pushup(p);pushup(pa);splay(p,0);return ; // Splay ????????????????? 69 } 70 pa = p; // ??! 71 p = ch[p][x > data[p]]; 72 if (!p) { 73 p = Newnode(pa,x); 74 ch[pa][x > data[pa]] = p; 75 pushup(p),pushup(pa);splay(p,0); 76 break; 77 } 78 } 79 } 80 void Clear(int p) { 81 siz[p] = cnt[p] = ch[p][0] = ch[p][1] = fa[p] = data[p] = 0; 82 } 83 void Delete(int x) { 84 getrnk(x); 85 int &p = Root,tmp; 86 if (cnt[p]) {cnt[p]--;pushup(p);return ;} 87 if (!ls && !rs) {Clear(p);Root = 0;return ;} 88 if (!ls || !rs) {tmp = p;p = ls?ls:rs;fa[p] = 0;Clear(tmp);return ;} 89 int pre = ls; 90 while (ch[pre][1]) pre = ch[pre][1]; 91 tmp = p;p = pre; 92 splay(p,0); 93 ch[p][1] = ch[tmp][1];fa[ch[tmp][1]] = p; 94 Clear(tmp);pushup(p); 95 } 96 int main() { 97 int T,opt,x; 98 scanf("%d",&T); 99 while (T--) { 100 scanf("%d%d",&opt,&x); 101 if (opt==1) Insert(x); 102 else if (opt==2) Delete(x); 103 else if (opt==3) printf("%d\n",getrnk(x)); 104 else if (opt==4) printf("%d\n",getkth(x)); 105 else if (opt==5) printf("%d\n",getkth(getrnk(x)-1)); 106 else printf("%d\n",getkth(getrnk(x+1))); 107 } 108 }
持续更新2018-05-02
1 #include<cstdio> 2 #include<cctype> 3 4 const int N = 1000100; 5 6 int siz[N],ch[N][2],fa[N],cnt[N],data[N]; 7 int Root,tn; 8 9 #define ls ch[p][0] 10 #define rs ch[p][1] 11 12 int son(int x) { 13 return x==ch[fa[x]][1]; 14 } 15 void pushup(int p) { 16 siz[p] = siz[ls] + siz[rs] + cnt[p]; 17 } 18 void rotate(int x) { 19 int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b]; 20 if (z) ch[z][c] = x;else Root = x;fa[x] = z; 21 ch[x][!b] = y;fa[y] = x; 22 ch[y][b] = a;if (a) fa[a] = y; 23 pushup(y),pushup(x); 24 } 25 void splay(int x,int rt) { 26 while (fa[x] != rt) { 27 int y = fa[x],z = fa[y]; 28 if (z==rt) rotate(x); 29 else { 30 if (son(x)==son(y)) rotate(y),rotate(x); 31 else rotate(x),rotate(x); 32 } 33 } 34 } 35 int getrnk(int k) { 36 int p = Root,ans = 0; 37 while (true) { 38 if (!p) return ans + 1; // 没有这个点 39 if (k < data[p]) p = ls; 40 else { 41 ans += (ls?siz[ls]:0); 42 if (k == data[p]) { 43 splay(p,0);return ans + 1; 44 } 45 ans += cnt[p]; 46 p = rs; 47 } 48 } 49 } 50 int getkth(int k) { 51 int p = Root; 52 while (true) { 53 if (k <= siz[ls]) p = ls; 54 else { 55 k -= ls?siz[ls]:0; 56 if (k<=cnt[p]) return data[p]; 57 k -= cnt[p]; 58 p = rs; 59 } 60 } 61 } 62 int Newnode(int pa,int d) { 63 ++tn;siz[tn] = cnt[tn] = 1;ch[tn][1] = ch[tn][0] = 0; 64 data[tn] = d;fa[tn] = pa; 65 return tn; 66 } 67 void Insert(int x) { 68 if (!Root) {Root = Newnode(0,x);return ;} 69 int p = Root,pa = 0; 70 while (true) { 71 if (data[p]==x) { 72 cnt[p] ++;pushup(p);pushup(pa);splay(p,0);return ; // Splay 为了更新新新加入节点后产生的变化。 73 } 74 pa = p; // 顺序! 75 p = ch[p][x > data[p]]; 76 if (!p) { 77 p = Newnode(pa,x); 78 ch[pa][x > data[pa]] = p; 79 pushup(p),pushup(pa);splay(p,0); 80 break; 81 } 82 } 83 } 84 void Clear(int p) { 85 siz[p] = cnt[p] = ch[p][0] = ch[p][1] = fa[p] = data[p] = 0; 86 } 87 void Delete(int x) { 88 getrnk(x); 89 int &p = Root,tmp; 90 if (cnt[p]) {cnt[p]--;pushup(p);return ;} 91 if (!ls && !rs) {Clear(p);Root = 0;return ;} 92 if (!ls || !rs) {tmp = p;p = ls?ls:rs;fa[p] = 0;Clear(tmp);return ;} 93 int pre = ls; 94 while (pre) pre = ch[pre][1]; 95 tmp = p;p = pre; 96 splay(p,0); 97 ch[p][1] = ch[tmp][1];fa[ch[tmp][1]] = p; 98 Clear(tmp);pushup(p); 99 } 100 int main() { 101 int T,opt,x; 102 scanf("%d",&T); 103 while (T--) { 104 scanf("%d%d",&opt,&x); 105 if (opt==1) Insert(x); 106 else if (opt==2) Delete(x); 107 else if (opt==3) printf("%d\n",getrnk(x)); 108 else if (opt==4) printf("%d\n",getkth(x)); 109 else if (opt==5) printf("%d\n",getkth(getrnk(x)-1)); 110 else printf("%d\n",getkth(getrnk(x+1))); 111 } 112 }
再一次更新2018-05-01
1 #include<cstdio> 2 #include<cctype> 3 4 const int N = 100010; 5 int fa[N],ch[N][2],siz[N],cnt[N],data[N]; 6 int tn,Root; 7 8 inline int read() { 9 int x = 0,f = 1;char ch = getchar(); 10 for (; !isdigit(ch); ch=getchar()) if(ch=='-') f=-1; 11 for (; isdigit(ch); ch=getchar()) x = x*10+ch-'0'; 12 return x * f; 13 } 14 #define ls ch[p][0] 15 #define rs ch[p][1] 16 inline int son(int x) { 17 return x == ch[fa[x]][1]; // - 18 } 19 inline void pushup(int x) { 20 siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + cnt[x]; 21 } 22 void rotate(int x) { 23 int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b]; 24 if (z) ch[z][c] = x;else Root = x;fa[x] = z; // 调整x的位置 25 ch[x][!b] = y;fa[y] = x; // 调整y的位置 26 ch[y][b] = a;if (a) fa[a] = y; // 给y另一个子节点 27 pushup(y);pushup(x); 28 } 29 void splay(int x,int rt) { 30 while (fa[x] != rt) { 31 int y = fa[x],z = fa[y]; 32 if (z==rt) rotate(x); 33 else { 34 if (son(x)==son(y)) rotate(y),rotate(x); 35 else rotate(x),rotate(x); 36 } 37 } 38 } 39 int getrnk(int k) { // 得到k的排名,位置 40 int p = Root,ans = 0; 41 while (true) { 42 if (p == 0) return ans + 1; 43 if (k < data[p]) p = ls; 44 else { 45 ans += (ls ? siz[ls] : 0); 46 if (k==data[p]) { 47 splay(p,0);return ans+1; 48 } 49 ans += cnt[p]; 50 p = rs; 51 } 52 } 53 } 54 int getkth(int k) { // 得到第k个数 55 int p = Root; 56 while (true) { 57 if (ls && k <= siz[ls]) p = ls; 58 else { 59 int tmp = (ls ? siz[ls] : 0) + cnt[p]; 60 if (k <= tmp) return data[p]; 61 k -= tmp; p = rs; 62 } 63 } 64 } 65 void newnode(int x,int pa,int d) { 66 ch[x][0] = ch[x][1] = 0;siz[x] = cnt[x] = 1; 67 data[x] = d;fa[x] = pa; 68 } 69 inline void Insert(int x) { // 插入 70 if (Root==0) { 71 ++tn; Root = tn;newnode(tn,0,x);return; 72 } 73 int p = Root,pa = 0; 74 while (true) { 75 if (x==data[p]) { 76 cnt[p]++;pushup(p);pushup(pa);splay(p,0);break; 77 } 78 pa = p; 79 p = ch[p][x > data[p]]; 80 if (p==0) { 81 p = ++tn;newnode(p,pa,x); 82 ch[pa][x > data[pa]] = p; 83 pushup(pa),splay(p,0);break; 84 } 85 } 86 } 87 inline void Clear(int x) { 88 ch[x][0] = ch[x][1] = fa[x] = siz[x] = cnt[x] = data[x] = 0; 89 } 90 inline void Delete(int x) { // 删除 91 getrnk(x); 92 int &p = Root; 93 if (cnt[p] > 1) {cnt[p]--;pushup(p);return;} 94 if (!ls && !rs) {Clear(p);p = 0;return;} 95 if (!ls || !rs) { 96 int tmp = p;p = ls==0?rs:ls;fa[p] = 0;Clear(tmp);return; 97 } 98 int tmp = p,pre = ls; // 找根节点的前一个-左子树的最右边 99 while (ch[pre][1]) pre = ch[pre][1]; 100 splay(pre,0); 101 rs = ch[tmp][1];fa[ch[tmp][1]] = p; 102 Clear(tmp); 103 pushup(p); 104 } 105 int main() { 106 int n = read(); 107 while (n--){ 108 int opt = read(),x = read(); 109 if (opt==1) Insert(x); 110 else if (opt==2) Delete(x); 111 else if (opt==3) printf("%d\n",getrnk(x)); 112 else if (opt==4) printf("%d\n",getkth(x)); 113 else if (opt==5) printf("%d\n",getkth(getrnk(x)-1)); 114 else printf("%d\n",getkth(getrnk(x+1))); 115 } 116 return 0; 117 }
更新了下板子
1 #include<cstdio> 2 3 const int N = 100010; 4 int fa[N],ch[N][2],siz[N],cnt[N],data[N]; 5 int tn,Root; 6 7 inline char nc() { 8 static char buf[100000],*p1 = buf,*p2 = buf; 9 return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF :*p1++; 10 } 11 inline int read() { 12 int x = 0,f = 1;char ch=nc(); 13 for (; ch<'0'||ch>'9'; ch = nc()) 14 if (ch == '-') f = -1; 15 for (; ch>='0'&&ch<='9'; ch = nc()) 16 x = x*10+ch-'0'; 17 return x * f; 18 } 19 inline int son(int x) { 20 return x == ch[fa[x]][1]; // - 21 } 22 inline void pushup(int x) { 23 siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + cnt[x]; 24 } 25 inline void rotate(int x) { 26 int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b]; 27 if (z) ch[z][c] = x;else Root = x;fa[x] = z; // 调整x的位置 28 ch[x][!b] = y;fa[y] = x; // 调整y的位置 29 ch[y][b] = a;if (a) fa[a] = y; // 给y另一个子节点 30 pushup(y);pushup(x); 31 } 32 inline void splay(int x,int rt) { 33 while (fa[x] != rt) { 34 int y = fa[x],z = fa[y]; 35 if (z==rt) rotate(x); 36 else { 37 if (son(x)==son(y)) rotate(y),rotate(x); 38 else rotate(x),rotate(x); 39 } 40 } 41 } 42 inline int getpre(int x) { //得到第一个比x小的数 43 int p = Root,ans; 44 while (p) { 45 if (x <= data[p]) p = ch[p][0]; 46 else ans = p,p = ch[p][1]; 47 } 48 return ans; 49 } 50 inline int getsuc(int x) { // 得到第一个比x大的数 51 int p = Root,ans; 52 while (p) { 53 if (x >= data[p]) p = ch[p][1]; 54 else ans = p,p = ch[p][0]; 55 } 56 return ans; 57 } 58 inline int getk(int k) { // 得到k的排名 59 int p = Root,ans = 0; 60 while (true) { 61 if (k < data[p]) p = ch[p][0]; 62 else { 63 ans += (ch[p][0] ? siz[ch[p][0]] : 0); 64 if (k==data[p]) { 65 splay(p,0);return ans+1; 66 } 67 ans += cnt[p]; 68 p = ch[p][1]; 69 } 70 } 71 } 72 inline int getkth(int k) { // 得到第k个数 73 int p = Root; 74 while (true) { 75 if (ch[p][0] && k <= siz[ch[p][0]]) p = ch[p][0]; 76 else { 77 int tmp = (ch[p][0] ? siz[ch[p][0]] : 0) + cnt[p]; 78 if (k <= tmp) return data[p]; 79 k -= tmp; p = ch[p][1]; 80 } 81 } 82 } 83 inline void Insert(int x) { // 插入 84 if (Root==0) { 85 ++tn; Root = tn; 86 ch[tn][1] = ch[tn][0] = fa[tn] = 0; 87 siz[tn] = cnt[tn] = 1;data[tn] = x; 88 return; 89 } 90 int p = Root,pa = 0; 91 while (true) { 92 if (x==data[p]) { 93 cnt[p]++;pushup(p);pushup(pa);splay(p,0);break; 94 } 95 pa = p; 96 p = ch[p][x > data[p]]; 97 if (p==0) { 98 tn++; 99 ch[tn][1] = ch[tn][0] = 0;siz[tn] = cnt[tn] = 1; 100 fa[tn] = pa;ch[pa][x > data[pa]] = tn;data[tn] = x; //- 101 pushup(pa),splay(tn,0);break; 102 } 103 } 104 } 105 inline void Clear(int x) { 106 ch[x][0] = ch[x][1] = fa[x] = siz[x] = cnt[x] = data[x] = 0; 107 } 108 inline void Delete(int x) { // 删除 109 getk(x); 110 if (cnt[Root] > 1) {cnt[Root]--;pushup(Root);return;} 111 if (!ch[Root][0] && !ch[Root][1]) {Clear(Root);Root = 0;return;} 112 if (!ch[Root][0]) { 113 int tmp = Root;Root = ch[Root][1];fa[Root] = 0;Clear(tmp);return; 114 } 115 else if (!ch[Root][1]) { 116 int tmp = Root;Root = ch[Root][0];fa[Root] = 0;Clear(tmp);return; 117 } 118 int tmp = Root,pre = ch[Root][0];//可以是getpre(data[Root]);等价于下面的while 119 while (ch[pre][1]) pre = ch[pre][1]; 120 splay(pre,0); 121 ch[Root][1] = ch[tmp][1]; 122 fa[ch[tmp][1]] = Root; 123 Clear(tmp); 124 pushup(Root); 125 } 126 int main() { 127 int n = read(); 128 while (n--){ 129 int opt = read(),x = read(); 130 if (opt==1) Insert(x); 131 else if (opt==2) Delete(x); 132 else if (opt==3) printf("%d\n",getk(x)); 133 else if (opt==4) printf("%d\n",getkth(x)); 134 else if (opt==5) printf("%d\n",data[getpre(x)]); 135 else printf("%d\n",data[getsuc(x)]); 136 } 137 return 0; 138 }
另一种写法,放一下吧
1 #include<cstdio> 2 3 const int N = 100010; 4 int fa[N],ch[N][2],siz[N],cnt[N],data[N]; 5 int tn,Root; 6 7 inline char nc() { 8 static char buf[100000],*p1 = buf,*p2 = buf; 9 return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF :*p1++; 10 } 11 inline int read() { 12 int x = 0,f = 1;char ch=nc(); 13 for (; ch<'0'||ch>'9'; ch = nc()) 14 if (ch == '-') f = -1; 15 for (; ch>='0'&&ch<='9'; ch = nc()) 16 x = x*10+ch-'0'; 17 return x * f; 18 } 19 inline int son(int x) { 20 return x == ch[fa[x]][1]; // - 21 } 22 inline void pushup(int x) { 23 siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + cnt[x]; 24 } 25 inline void rotate(int x) { 26 int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b]; 27 if (z) ch[z][c] = x;else Root = x;fa[x] = z; // 调整x的位置 28 ch[x][!b] = y;fa[y] = x; // 调整y的位置 29 ch[y][b] = a;if (a) fa[a] = y; // 给y另一个子节点 30 pushup(y);pushup(x); 31 } 32 inline void splay(int x,int rt) { 33 while (fa[x] != rt) { 34 int y = fa[x],z = fa[y]; 35 if (z==rt) rotate(x); 36 else { 37 if (son(x)==son(y)) rotate(y),rotate(x); 38 else rotate(x),rotate(x); 39 } 40 } 41 } 42 inline int getpre(int x) { //得到第一个比x小的数 43 int p = ch[Root][0]; 44 while (ch[p][1]) p = ch[p][1]; 45 return p; 46 } 47 inline int getsuc(int x) { // 得到第一个比x大的数 48 int p = ch[Root][1]; 49 while (ch[p][0]) p = ch[p][0]; 50 return p; 51 } 52 inline int getk(int k) { // 得到k的排名 53 int p = Root,ans = 0; 54 while (true) { 55 if (k < data[p]) p = ch[p][0]; 56 else { 57 ans += (ch[p][0] ? siz[ch[p][0]] : 0); 58 if (k==data[p]) { 59 splay(p,0);return ans+1; 60 } 61 ans += cnt[p]; 62 p = ch[p][1]; 63 } 64 } 65 } 66 inline int getkth(int k) { // 得到第k个数 67 int p = Root; 68 while (true) { 69 if (ch[p][0] && k <= siz[ch[p][0]]) p = ch[p][0]; 70 else { 71 int tmp = (ch[p][0] ? siz[ch[p][0]] : 0) + cnt[p]; 72 if (k <= tmp) return data[p]; 73 k -= tmp; p = ch[p][1]; 74 } 75 } 76 } 77 inline void Insert(int x) { // 插入 78 if (Root==0) { 79 ++tn; Root = tn; 80 ch[tn][1] = ch[tn][0] = fa[tn] = 0; 81 siz[tn] = cnt[tn] = 1;data[tn] = x; 82 return; 83 } 84 int p = Root,pa = 0; 85 while (true) { 86 if (x==data[p]) { 87 cnt[p]++;pushup(p);pushup(pa);splay(p,0);break; 88 } 89 pa = p; 90 p = ch[p][x > data[p]]; 91 if (p==0) { 92 tn++; 93 ch[tn][1] = ch[tn][0] = 0;siz[tn] = cnt[tn] = 1; 94 fa[tn] = pa;ch[pa][x > data[pa]] = tn;data[tn] = x; //- 95 pushup(pa),splay(tn,0);break; 96 } 97 } 98 } 99 inline void Clear(int x) { 100 ch[x][0] = ch[x][1] = fa[x] = siz[x] = cnt[x] = data[x] = 0; 101 } 102 inline void Delete(int x) { // 删除 103 getk(x); 104 if (cnt[Root] > 1) {cnt[Root]--;pushup(Root);return;} 105 if (!ch[Root][0] && !ch[Root][1]) {Clear(Root);Root = 0;return;} 106 if (!ch[Root][0]) { 107 int tmp = Root;Root = ch[Root][1];fa[Root] = 0;Clear(tmp);return; 108 } 109 else if (!ch[Root][1]) { 110 int tmp = Root;Root = ch[Root][0];fa[Root] = 0;Clear(tmp);return; 111 } 112 int tmp = Root,pre = ch[Root][0];//可以是getpre(data[Root]);等价于下面的while 113 while (ch[pre][1]) pre = ch[pre][1]; 114 splay(pre,0); 115 ch[Root][1] = ch[tmp][1]; 116 fa[ch[tmp][1]] = Root; 117 Clear(tmp); 118 pushup(Root); 119 } 120 int main() { 121 int n = read(); 122 while (n--){ 123 int opt = read(),x = read(); 124 if (opt==1) Insert(x); 125 else if (opt==2) Delete(x); 126 else if (opt==3) printf("%d\n",getk(x)); 127 else if (opt==4) printf("%d\n",getkth(x)); 128 else if (opt==5) Insert(x),printf("%d\n",data[getpre(x)]),Delete(x); 129 else Insert(x),printf("%d\n",data[getsuc(x)]),Delete(x); 130 } 131 return 0; 132 }
没有重复数字的情况:
getk和getkth函数
1 // 只在没有重复数字是使用 2 inline int getk(int k) { 3 int p = Root,ans = 0; 4 while (true) { 5 if (k == data[p]) {splay(p,0);return ans+1;} 6 if (k < data[p]) p = ch[p][0]; 7 else { 8 ans += (ch[p][0] ? siz[ch[p][0]] : 0) + 1; 9 p = ch[p][1]; 10 } 11 } 12 } 13 inline int getkth(int k) { 14 int p = Root; 15 while (true) { 16 if (k == siz[ch[p][0]]+1) return p; 17 if (ch[p][0] && k <= siz[ch[p][0]]) p = ch[p][0]; 18 else { 19 k -= ((ch[p][0] ? siz[ch[p][0]] : 0) + 1); 20 p = ch[p][1]; 21 } 22 } 23 }
insert,delete
1 inline void Insert(int x) { 2 if (Root==0) { 3 ++tn;Root = tn; 4 ch[tn][1] = ch[tn][0] = fa[tn] = 0; 5 siz[tn] = 1;data[tn] = x; 6 return ; 7 } 8 int p = Root,pa = 0; 9 while (true) { 10 pa = p; 11 p = ch[p][x > data[p]]; 12 if (p==0) { 13 ++tn; 14 ch[tn][1] = ch[tn][0] = 0;fa[tn] = pa; 15 ch[pa][x > data[pa]] = tn; 16 siz[tn] = 1;data[tn] = x; 17 pushup(pa),splay(tn,0);break; 18 } 19 } 20 } 21 inline void Clear(int x) { 22 ch[x][0] = ch[x][1] = fa[x] = siz[x] = data[x] = 0; 23 } 24 inline void Delete(int x) { 25 getk(x); 26 if (!ch[Root][0] && !ch[Root][1]) { Clear(Root);Root = 0;return;} 27 if (!ch[Root][0]) { 28 int tmp = Root;Root = ch[Root][1];fa[Root] = 0;Clear(tmp);return; 29 } 30 else if (!ch[Root][1]) { 31 int tmp = Root;Root = ch[Root][0];fa[Root] = 0;Clear(tmp);return; 32 } 33 int tmp = Root,pre = ch[Root][0]; 34 while (ch[pre][1]) pre = ch[pre][1]; 35 splay(pre,0); 36 ch[Root][1] = ch[tmp][1]; 37 fa[ch[tmp][1]] = Root; 38 Clear(tmp); 39 pushup(Root); 40 }
查找大于等于x的数或者小于等于:
getpre和getsuc函数
1 //这两个函数可以等于查找的数 2 inline int getpre(int x) { // 返回第一个小于等于x的数 3 int p = Root,ans = 0; 4 while (p) { 5 if (x < data[p]) p = ch[p][0]; 6 else ans = p,p = ch[p][1]; 7 } 8 return ans; 9 } 10 inline int getsuc(int x) { // 返回第一个大于等于x的数 11 int p = Root,ans = 0; 12 while (p) { 13 if (x > data[p]) p = ch[p][1]; 14 else ans = p,p = ch[p][1]; 15 } 16 }
getpre,getsuc函数另一种操作:
getpre(x):找x的前驱,首先找到x的排名k = getk(x),然后求出排名为k-1的数:pre=getkth(k-1);
getsuc同理