P3369 【模板】普通平衡树
https://www.luogu.org/problemnew/show/P3369
BST
1 struct BST { 2 int l, r; // 左右子节点在数组中的下标 3 int val; // 节点关键码 4 } a[SIZE]; // 数组模拟链表 5 int tot, root, INF = 1<<30; 6 7 int New(int val) { 8 a[++tot].val = val; 9 return tot; 10 } 11 12 void Build() { 13 New(-INF), New(INF); 14 root = 1, a[1].r = 2; 15 } 16 17 int Get(int p, int val) { 18 if (p == 0) return 0; // 检索失败 19 if (val == a[p].val) return p; // 检索成功 20 return val < a[p].val ? Get(a[p].l, val) : Get(a[p].r, val); 21 } 22 23 void Insert(int &p, int val) { 24 if (p == 0) { 25 p = New(val); // 注意p是引用,其父节点的l或r值会被同时更新 26 return; 27 } 28 if (val == a[p].val) return; 29 if (val < a[p].val) Insert(a[p].l, val); 30 else Insert(a[p].r, val); 31 } 32 33 int GetNext(int val) { 34 int ans = 2; // a[2].val==INF 35 int p = root; 36 while (p) { 37 if (val == a[p].val) { // 检索成功 38 if (a[p].r > 0) { // 有右子树 39 p = a[p].r; 40 // 右子树上一直向左走 41 while (a[p].l > 0) p = a[p].l; 42 ans = p; 43 } 44 break; 45 } 46 // 每经过一个节点,都尝试更新后继 47 if (a[p].val > val && a[p].val < a[ans].val) ans = p; 48 p = val < a[p].val ? a[p].l : a[p].r; 49 } 50 return ans; 51 } 52 53 void Remove(int val) { 54 // 检索val,得到节点p 55 int &p = root; 56 while (p) { 57 if (val == a[p].val) break; 58 p = val < a[p].val ? a[p].l : a[p].r; 59 } 60 if (p == 0) return; 61 if (a[p].l == 0) { // 没有左子树 62 p = a[p].r; // 右子树代替p的位置,注意p是引用 63 } 64 else if (a[p].r == 0) { // 没有右子树 65 p = a[p].l; // 左子树代替p的位置,注意p是引用 66 } 67 else { // 既有左子树又有右子树 68 // 求后继节点 69 int next = a[p].r; 70 while (a[next].l > 0) next = a[next].l; 71 // next一定没有左子树,直接删除 72 Remove(a[next].val); 73 // 令节点next代替节点p的位置 74 a[next].l = a[p].l, a[next].r = a[p].r; 75 p = next; // 注意p是引用 76 } 77 }
treap
利用随机权值维护堆的形态
1 const int N=100010,INF=1<<30; 2 struct treap{int l,r,c,dat,cnt,size;}a[N]; 3 int m,tot,root; 4 5 int newnode(int val) 6 { 7 a[++tot].c=val; 8 a[tot].dat=rand(); 9 a[tot].size=a[tot].cnt=1; 10 return tot; 11 } 12 13 void update(int x) 14 { 15 a[x].size=a[a[x].l].size+a[a[x].r].size+a[x].cnt; 16 } 17 18 void build() 19 { 20 newnode(-INF),newnode(INF); 21 root=1,a[1].r=2; 22 update(root); 23 } 24 25 void zlg(int &p)//zag 26 { 27 int q=a[p].r; 28 a[p].r=a[q].l,a[q].l=p,p=q; 29 update(a[p].l),update(p); 30 } 31 void zrg(int &p)//zig 32 { 33 int q=a[p].l; 34 a[p].l=a[q].r,a[q].r=p,p=q; 35 update(a[p].r),update(p); 36 } 37 38 void insert(int &p,int val) 39 { 40 if(p==0) {p=newnode(val);return;} 41 if(a[p].c==val) {++a[p].cnt,++a[p].size;return;} 42 if(val<a[p].c) 43 { 44 insert(a[p].l,val); 45 if(a[p].dat<a[a[p].l].dat) zrg(p); 46 } 47 else 48 { 49 insert(a[p].r,val); 50 if(a[p].dat<a[a[p].r].dat) zlg(p); 51 } 52 update(p); 53 } 54 55 int grbv(int p,int val) 56 { 57 if(p==0) return 0; 58 if(a[p].c==val) return a[a[p].l].size+1; 59 if(a[p].c>val) return grbv(a[p].l,val); 60 return grbv(a[p].r,val)+a[a[p].l].size+a[p].cnt; 61 } 62 63 int gvbr(int p,int ran) 64 { 65 if(p==0) return INF; 66 if(a[a[p].l].size>=ran) return gvbr(a[p].l,ran); 67 else if(a[a[p].l].size+a[p].cnt>=ran) return a[p].c; 68 else return gvbr(a[p].r,ran-a[a[p].l].size-a[p].cnt); 69 } 70 71 int getnext(int val) 72 { 73 int p=root,ans=2; 74 while(p) 75 { 76 if(a[p].c==val) 77 { 78 if(a[p].r>0) 79 { 80 p=a[p].r; 81 while(a[p].l>0)p=a[p].l; 82 ans=p; 83 } 84 break; 85 } 86 if(a[p].c>val&&a[p].c<a[ans].c) ans=p; 87 if(val<a[p].c) p=a[p].l; 88 else p=a[p].r; 89 } 90 return a[ans].c; 91 } 92 93 int getlast(int val) 94 { 95 int p=root,ans=1; 96 while(p) 97 { 98 if(a[p].c==val)//||(a[p].c>val&&a[p].l==0) 99 { 100 if(a[p].l>0) 101 { 102 p=a[p].l; 103 while(a[p].r>0) p=a[p].r; 104 ans=p; 105 } 106 break; 107 } 108 if(a[p].c<val&&a[p].c>a[ans].c) ans=p; 109 if(val<a[p].c) p=a[p].l; 110 else p=a[p].r; 111 } 112 return a[ans].c; 113 } 114 115 void remove(int &p,int val) 116 { 117 if(p==0) return; 118 if(a[p].c==val) 119 { 120 if(a[p].cnt>1) 121 { 122 a[p].cnt--,update(p); 123 return; 124 } 125 if(a[p].l||a[p].r) 126 { 127 if(a[p].r==0 || a[a[p].l].dat>a[a[p].r].dat) 128 zrg(p),remove(a[p].r,val); 129 else zlg(p),remove(a[p].l,val); 130 update(p); 131 } 132 else p=0; 133 return; 134 } 135 if(val<a[p].c) remove(a[p].l,val); 136 else remove(a[p].r,val); 137 update(p); 138 } 139 140 int main() 141 { 142 srand(time(NULL)); 143 cin>>m;build(); 144 FOR(i,1,m) 145 { 146 int opt,x;cin>>opt>>x; 147 switch(opt) 148 { 149 case 1:insert(root,x);break; 150 case 3:cout<<grbv(root,x)-1<<endl;break; 151 case 4:cout<<gvbr(root,x+1)<<endl;break; 152 case 5:cout<<getlast(x)<<endl;break; 153 case 6:cout<<getnext(x)<<endl;break; 154 case 2:remove(root,x);break; 155 } 156 } 157 return 0; 158 }