1. 程式人生 > >【模板】無旋Treap(FHQ)

【模板】無旋Treap(FHQ)

如題,這是一個模板。。。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 #include <cctype>
  6 
  7 inline void read(int & x)
  8 {
  9     x = 0;
 10     int k = 1;
 11     char c = getchar();
 12     while (!isdigit(c))
13 if (c == '-') c = getchar(), k = -1; 14 else c = getchar(); 15 while (isdigit(c)) 16 x = (x << 1) + (x << 3) + (c ^ 48), 17 c = getchar(); 18 x *= k; 19 } 20 21 const int MAXN = 101010; 22 int seed = 1024; 23 int m, x, tot, opt, rt = 0
; 24 int siz[MAXN], val[MAXN], rnd[MAXN], son[MAXN][2]; 25 26 inline int Rand() 27 { 28 return seed = (int)seed * 482711LL % 2147483647; 29 } 30 31 inline void Pushup(int u) 32 { 33 siz[u] = siz[son[u][0]] + siz[son[u][1]] + 1; 34 } 35 36 inline int New(int x) 37
{ 38 siz[++tot] = 1; 39 val[tot] = x; 40 rnd[tot] = Rand(); 41 son[tot][0] = son[tot][1] = 0; 42 return tot; 43 } 44 45 inline void Split(int u, int x, int &a, int &b) 46 { 47 if (!u) { a = b = 0; return; } 48 if (val[u] <= x) a = u, Split(son[u][1], x, son[a][1], b); 49 else b = u, Split(son[u][0], x, a, son[b][0]); 50 Pushup(u); 51 } 52 53 inline void Split_siz(int u, int k, int &a, int &b) 54 { 55 if (!u) { a = b = 0; return; } 56 if (k <= siz[son[u][0]]) b = u, Split_siz(son[u][0], k, a, son[b][0]); 57 else a = u, Split_siz(son[u][1], k - siz[son[u][0]] - 1, son[a][1], b); 58 Pushup(u); 59 } 60 61 inline void Merge(int & u, int a, int b) 62 { 63 if (!a || !b) { u = a | b; return; } 64 if (rnd[a] < rnd[b]) u = a, Merge(son[u][1], son[a][1], b); 65 else u = b, Merge(son[u][0], a, son[b][0]); 66 Pushup(u); 67 } 68 69 inline int Findkth(int u, int k) 70 { 71 while (siz[son[u][0]] + 1 != k) 72 if (siz[son[u][0]] >= k) u = son[u][0]; 73 else k -= siz[son[u][0]] + 1, u = son[u][1]; 74 return u; 75 } 76 77 inline void Insert(int x) 78 { 79 int a = 0, b = 0, c = 0; 80 c = New(x); 81 Split(rt, x, a, b); 82 Merge(a, a, c); 83 Merge(rt, a, b); 84 } 85 86 inline void Delete(int x) 87 { 88 int a = 0, b = 0, c = 0; 89 Split(rt, x, a, b); 90 Split(a, x - 1, a, c); 91 Merge(c, son[c][0], son[c][1]); 92 Merge(a, a, c); 93 Merge(rt, a, b); 94 } 95 96 inline void Getrank(int x) 97 { 98 int a = 0, b = 0; 99 Split(rt, x - 1, a, b); 100 printf("%d\n", siz[a] + 1); 101 Merge(rt, a, b); 102 } 103 104 inline void Getkth(int k) 105 { 106 int a = 0, b = 0, c = 0; 107 //·½·¨1£ºÓú¯ÊýÄõÚk´ó 108 printf("%d\n", val[Findkth(rt, k)]); 109 return; 110 111 //·½·¨2£º°´siz·ÖÁÑÄóöc 112 Split_siz(rt, k, a, b); 113 Split_siz(a, k - 1, a, c); 114 printf("%d\n", val[c]); 115 Merge(a, a, c); 116 Merge(rt, a, b); 117 } 118 119 inline void Pre(int x) 120 { 121 int a = 0, b = 0; 122 Split(rt, x - 1, a, b); 123 printf("%d\n", val[Findkth(a, siz[a])]); 124 Merge(rt, a, b); 125 } 126 127 inline void Suf(int x) 128 { 129 int a = 0, b = 0; 130 Split(rt, x, a, b); 131 printf("%d\n", val[Findkth(b, 1)]); 132 Merge(rt, a, b); 133 } 134 135 signed main() 136 { 137 read(m); 138 for (int i = 1; i <= m; ++i) 139 { 140 read(opt), read(x); 141 if (opt == 1) Insert(x); 142 if (opt == 2) Delete(x); 143 if (opt == 3) Getrank(x); 144 if (opt == 4) Getkth(x); 145 if (opt == 5) Pre(x); 146 if (opt == 6) Suf(x); 147 } 148 return 0; 149 }