模板无旋Treap(FHQ)

Posted yanyiming10243247

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板无旋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
", 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
", 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
", 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
", 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
", 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 }

 

以上是关于模板无旋Treap(FHQ)的主要内容,如果未能解决你的问题,请参考以下文章

算法学习Fhq-Treap(无旋Treap)

[luogu3391] 模板文艺平衡树(fhq-treap反转区间)

「学习笔记」重修 FHQ-treap

平衡树——FHQ Treap

fhq-Treap原理

数据结构FHQ Treap详解