void pushup(int node_id){ int l=splay[node_id].ch[0]; int r=splay[node_id].ch[1]; splay[node_id].size=splay[l].size+splay[r].size+splay[node_id].cnt; }
单旋转操作
每次旋转操作其实上都是将父亲和儿子进行交换,就是x和x.parent进行交换.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
void rotate (int x) { int fa = splay[x].parent; int Gfa = splay[fa].parent; int k = (splay[fa].ch[1]==x); int g = (splay[Gfa].ch[1]==fa); splay[Gfa].ch[g]=x; splay[x].parent=Gfa; splay[fa].ch[k]=splay[x].ch[k^1]; splay[splay[x].ch[k^1]].parent=fa; splay[x].ch[k ^ 1]=fa; splay[fa].parent=x; pushup(fa); pushup(x); }
int PreSuf (int x, int f) { find (x); if (splay[root].val>x&&f) return root; if (splay[root].val < x && !f) return root; int u = splay[root].ch[f]; if (!u) return 0; while (splay[u].ch[f ^ 1]) u =splay[u].ch[f ^ 1]; return u; }
Delete操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14
void Delete (int x) { int pre = PreSuf(x,0); int suf = PreSuf(x,1); splayed(pre,0); splayed(suf,pre); int u = splay[suf].ch[0]; if (splay[u].cnt>1) { splay[u].cnt--; splayed ( u, 0 ); } else{ splay[suf].ch[0] = 0; } }
int findkth (int x) { if (splay[root].size<x) return -1; int u=root; while (1) { if ( x <= splay[splay[u].ch[0]].size ) u = splay[u].ch[0]; else if ( x <= splay[u].cnt + splay[splay[u].ch[0]].size ) return u; else { x -= ( splay[splay[u].ch[0]].size + splay[u].cnt ); u = splay[u].ch[1]; } } }
#include <stdio.h> #include <stdlib.h> #define N 1000005 #define INF 0x7f7f7f7f struct splay{ int ch[2]; int val;//数值 int size;//子树大小 int cnt;//每个节点所含副本数 int parent; }splay[N]; int total; int root; int na; void pushup(int node_id){ int l=splay[node_id].ch[0]; int r=splay[node_id].ch[1]; splay[node_id].size=splay[l].size+splay[r].size+splay[node_id].cnt; }
void rotate (int x) { int fa = splay[x].parent; int Gfa = splay[fa].parent; int k = (splay[fa].ch[1]== x); splay[Gfa].ch[splay[Gfa].ch[1]==fa] = x; splay[x].parent = Gfa; splay[fa].ch[k] = splay[x].ch[k^1]; splay[splay[x].ch[k^1]].parent= fa; splay[x].ch[k ^ 1] = fa; splay[fa].parent = x; pushup(fa); pushup(x); } //将x旋转到goal的儿子 void splayed ( int x, int goal ) { while (splay[x].parent != goal) { int fa = splay[x].parent, Gfa = splay[fa].parent; if (Gfa!= goal ) ( (splay[Gfa].ch[0] == fa) ^ (splay[fa].ch[0] == x)) ? rotate(x) : rotate (fa); rotate (x); } if (!goal) root=x; } void insert(int x) { int u=root, fa=0; while (u && splay[u].val!=x) { fa = u; u=splay[u].ch[x>splay[u].val]; } if (u) splay[u].cnt ++; else { u=++total; if (fa) splay[fa].ch[x > splay[fa].val] = u; splay[u].ch[0] = splay[u].ch[1] = 0; splay[u].val = x; splay[u].parent = fa; splay[u].cnt = splay[u].size = 1; } splayed(u,0); }
void find(int x){ if (!root) return; int u=root; while (splay[u].ch[x > splay[u].val] && x!=splay[u].val) u=splay[u].ch[x > splay[u].val]; splayed (u,0); } int PreSuf (int x, int f) { find (x); if (splay[root].val>x&&f) return root; if (splay[root].val < x && !f) return root; int u = splay[root].ch[f]; if (!u) return 0; while (splay[u].ch[f ^ 1]) u =splay[u].ch[f ^ 1]; return u; }
void Delete (int x) { int pre = PreSuf(x,0); int suf = PreSuf(x,1); splayed(pre,0); splayed(suf,pre); int u = splay[suf].ch[0]; if (splay[u].cnt>1) { splay[u].cnt--; splayed ( u, 0 ); } else{ splay[suf].ch[0] = 0; } }
int findkth (int x) { if (splay[root].size<x) return -1; int u=root; while (1) { if ( x <= splay[splay[u].ch[0]].size ) u = splay[u].ch[0]; else if ( x <= splay[u].cnt + splay[splay[u].ch[0]].size ) return u; else { x -= ( splay[splay[u].ch[0]].size + splay[u].cnt ); u = splay[u].ch[1]; } } } void build(){ insert(INF); insert(-INF); } int main(){ int n; build(); scanf("%d",&n); int opt,x; int u; while(n--){ scanf("%d %d",&opt,&x); switch (opt) { case 1: insert(x); break; case 2: Delete(x); break; case 3: find(x); printf("%d\n",splay[splay[root].ch[0]].size); break; case 4: u=findkth(x+1); printf("%d\n",splay[u].val); break; case 5: u=PreSuf(x, 0); printf("%d\n",splay[u].val); break; case 6: u=PreSuf(x, 1); printf("%d\n",splay[u].val); break; default: break; } } }