# TTT(Tree套Tree)

1.查询x在[l, r]的排名。

2.查询[l, r]中排名为k的值。

3.修改某个数。

4.查询[l, r]中x的前驱。

5.查询[l, r]中x的后继。

①线段树套平衡树。

  1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 #include <queue>
5
6 const int M = 1500010, INF = 2147483647, N = 100010;
7
8 int tot, s[M][2], fa[M], siz[M], cnt[M], val[M];
9 std::queue<int> Rest;
10
11 struct Node {
12     int x, y;
13 }node[N];
14
15 struct Splay {
16
17     int root;
18
19     inline void pushup(int x) {
20         siz[x] = siz[s[x][0]] + siz[s[x][1]] + cnt[x];
21         if(!fa[x]) {
22             root = x;
23         }
24         return;
25     }
26
27     inline void rotate(int x) {
28         int y = fa[x];
29         int z = fa[y];
30         bool f = (s[y][1] == x);
31
32         fa[x] = z;
33         if(z) {
34             s[z][s[z][1] == y] = x;
35         }
36         s[y][f] = s[x][!f];
37         if(s[x][!f]) {
38             fa[s[x][!f]] = y;
39         }
40         s[x][!f] = y;
41         fa[y] = x;
42
43         pushup(y);
44         pushup(x);
45         return;
46     }
47
48     inline void splay(int x, int g = 0) {
49         int y = fa[x];
50         int z = fa[y];
51         while(y != g) {
52             if(z != g) {
53                 (s[z][1] == y) ^ (s[y][1] == x) ?
54                 rotate(x) : rotate(y);
55             }
56             rotate(x);
57             y = fa[x];
58             z = fa[y];
59         }
60         return;
61     }
62
63     inline int np(int c, int f, int sum = 1) {
64         int p;
65         if(Rest.empty()) {
66             p = ++tot;
67         }
68         else {
69             p = Rest.front();
70             Rest.pop();
71         }
72         fa[p] = f;
73         s[p][0] = s[p][1] = 0;
74         siz[p] = cnt[p] = sum;
75         val[p] = c;
76         return p;
77     }
78
79     inline void insert(int c) {
80         int p = root;
81         while(1) {
82             siz[p]++;
83             if(val[p] == c) {
84                 cnt[p]++;
85                 break;
86             }
87             if(c < val[p] && s[p][0]) {
88                 p = s[p][0];
89             }
90             else if(val[p] < c && s[p][1]) {
91                 p = s[p][1];
92             }
93             else {
94                 bool f = (val[p] < c);
95                 s[p][f] = np(c, p);
96                 break;
97             }
98         }
99         splay(p);
100         return;
101     }
102
103     inline int getPbyV(int c) { // if exist return Node else return neighbor
104         int p = root;
105         while(1) {
106             if(val[p] == c) {
107                 break;
108             }
109             else if(c < val[p] && s[p][0]) {
110                 p = s[p][0];
111             }
112             else if(val[p] < c && s[p][1]) {
113                 p = s[p][1];
114             }
115             else {
116                 break;
117             }
118         }
119         return p;
120     }
121
122     inline int getRP() {
123         int p = s[root][1];
124         while(s[p][0]) {
125             p = s[p][0];
126         }
127         return p;
128     }
129
130     inline int getLP() {
131         int p = s[root][0];
132         while(s[p][1]) {
133             p = s[p][1];
134         }
135         return p;
136     }
137
138     inline void del(int c) {
139         int x = getPbyV(c);
140         splay(x);
141         if(cnt[x] > 1) {
142             cnt[x]--;
143             siz[x]--;
144             return;
145         }
146         int y = getRP();
147         splay(y, x);
148         fa[y] = 0;
149         s[y][0] = s[x][0];
150         fa[s[x][0]] = y;
151         pushup(y);
152         Rest.push(x);
153         return;
154     }
155
156     inline int getPre(int c) {
157         int p = getPbyV(c);
158         splay(p);
159         if(val[p] >= c) {
160             p = getLP();
161             splay(p);
162             return val[p];
163         }
164         else {
165             return val[p];
166         }
167     }
168
169     inline int getNex(int c) {
170         int p = getPbyV(c);
171         splay(p);
172         if(val[p] <= c) {
173             p = getRP();
174             splay(p);
175             return val[p];
176         }
177         else {
178             return val[p];
179         }
180     }
181
182     inline int getRbyV(int c) {
183         int p = getPbyV(c);
184         splay(p);
185         if(val[p] < c) {
186             p = getRP();
187             splay(p);
188         }
189         return siz[s[p][0]];
190     }
191
192     int build(int l, int r, int f) {
193         if(l == r) {
194             return np(node[r].x, f, node[r].y);
195         }
196         int mid = (l + r) >> 1;
197         int p = np(node[mid].x, f, node[mid].y);
198         if(l < mid) {
199             s[p][0] = build(l, mid - 1, p);
200         }
201         if(mid < r) {
202             s[p][1] = build(mid + 1, r, p);
203         }
204         pushup(p);
205         return p;
206     }
207
208     inline void init(int *a, int n) {
209         int t = 1;
210         node[1].x = a[1];
211         node[1].y = 1;
212         for(int i = 2; i <= n; i++) {
213             if(a[i] != a[i - 1]) {
214                 node[++t].x = a[i];
215                 node[t].y = 0;
216             }
217             node[t].y++;
218         }
219         root = build(1, t, 0);
220         insert(INF);
221         insert(-INF);
222         return;
223     }
224
225     void out(int x) {
226         if(x == 0) {
227             x = root;
228         }
229         if(s[x][0]) {
230             out(s[x][0]);
231         }
232         for(int i = 1; i <= cnt[x]; i++) {
233             printf("%d ", val[x]);
234         }
235         if(s[x][1]) {
236             out(s[x][1]);
237         }
238         return;
239     }
240     // over
241 }spt[N << 2];
242
243 int large[N << 2], small[N << 2], a[N], b[N], c[N];
244
245 inline void pushup(int o) {
246     int ls = o << 1, rs = o << 1 | 1;
247     small[o] = std::min(small[ls], small[rs]);
248     large[o] = std::max(large[ls], large[rs]);
249     return;
250 }
251
252 int getRank(int L, int R, int v, int l, int r, int o) {
253     if(L <= l && r <= R) {
254         return spt[o].getRbyV(v) - 1;
255     }
256     int mid = (l + r) >> 1, ans = 0;
257     if(L <= mid) {
258         ans += getRank(L, R, v, l, mid, o << 1);
259     }
260     if(mid < R) {
261         ans += getRank(L, R, v, mid + 1, r, o << 1 | 1);
262     }
263     return ans;
264 }
265
266 int getPre(int L, int R, int v, int l, int r, int o) {
267     if(L <= l && r <= R) {
268         return spt[o].getPre(v);
269     }
270     int ans = -INF, mid = (l + r) >> 1;
271     if(L <= mid) {
272         ans = std::max(ans, getPre(L, R, v, l, mid, o << 1));
273     }
274     if(mid < R) {
275         ans = std::max(ans, getPre(L, R, v, mid + 1, r, o << 1 | 1));
276     }
277     return ans;
278 }
279
280 int getNex(int L, int R, int v, int l, int r, int o) {
281     if(L <= l && r <= R) {
282         return spt[o].getNex(v);
283     }
284     int mid = (l + r) >> 1, ans = INF;
285     if(L <= mid) {
286         ans = std::min(ans, getNex(L, R, v, l, mid, o << 1));
287     }
288     if(mid < R) {
289         ans = std::min(ans, getNex(L, R, v, mid + 1, r, o << 1 | 1));
290     }
291     return ans;
292 }
293
294 void change(int p, int v, int l, int r, int o) {
295     spt[o].del(a[p]);
296     spt[o].insert(v);
297     if(l == r) {
298         a[p] = large[o] = small[o] = v;
299         return;
300     }
301     int mid = (l + r) >> 1;
302     if(p <= mid) {
303         change(p, v, l, mid, o << 1);
304     }
305     else {
306         change(p, v, mid + 1, r, o << 1 | 1);
307     }
308     pushup(o);
309     return;
310 }
311
312 inline void merge(int l, int r) {
313     memcpy(c + l, b + l, (r - l + 1) * sizeof(int));
314     int mid = (l + r) >> 1;
315     int i = l, j = mid + 1, t = l;
316     while(t <= r) {
317         if(j > r || (i <= mid && c[i] < c[j])) {
318             b[t++] = c[i];
319             i++;
320         }
321         else {
322             b[t++] = c[j];
323             j++;
324         }
325     }
326     return;
327 }
328
329 void build(int l, int r, int o) {
330     if(l == r) {
331         spt[o].init(b + r - 1, 1);
332         small[o] = large[o] = b[r];
333         return;
334     }
335     int mid = (l + r) >> 1;
336     build(l, mid, o << 1);
337     build(mid + 1, r, o << 1 | 1);
338     merge(l, r);
339     spt[o].init(b + l - 1, r - l + 1);
340     pushup(o);
341     return;
342 }
343
344 int getMax(int L, int R, int l, int r, int o) {
345     if(L <= l && r <= R) {
346         return large[o];
347     }
348     int mid = (l + r) >> 1, ans = -INF;
349     if(L <= mid) {
350         ans = std::max(ans, getMax(L, R, l, mid, o << 1));
351     }
352     if(mid < R) {
353         ans = std::max(ans, getMax(L, R, mid + 1, r, o << 1 | 1));
354     }
355     return ans;
356 }
357
358 int getMin(int L, int R, int l, int r, int o) {
359     if(L <= l && r <= R) {
360         return small[o];
361     }
362     int mid = (l + r) >> 1, ans = INF;
363     if(L <= mid) {
364         ans = std::min(ans, getMin(L, R, l, mid, o << 1));
365     }
366     if(mid < R) {
367         ans = std::min(ans, getMin(L, R, mid + 1, r, o << 1 | 1));
368     }
369     return ans;
370 }
371
372 void out(int l, int r, int o) {
373     printf("out %d %d : ", l, r);
374     spt[o].out(0);
375     puts("");
376     if(l == r) {
377         return;
378     }
379     int mid = (l + r) >> 1;
380     out(l, mid, o << 1);
381     out(mid + 1, r, o << 1 | 1);
382     return;
383 }
384
385 int main() {
386
387     int n, m;
388     scanf("%d%d", &n, &m);
389     for(int i = 1; i <= n; i++) {
390         scanf("%d", &a[i]);
391         b[i] = a[i];
392     }
393     build(1, n, 1);
394
395     for(int i = 1, x, y, z, f; i <= m; i++) {
396         scanf("%d%d%d", &f, &x, &y);
397         if(f == 1) {
398             scanf("%d", &z);
399             int t = getRank(x, y, z, 1, n, 1);
400             printf("%d\n", t + 1);
401         }
402         else if(f == 2) {
403             scanf("%d", &z);
404             int l = getMin(x, y, 1, n, 1), r = getMax(x, y, 1, n, 1);
405             while(l < r) {
406                 int mid = (l + r + 1) >> 1;
407                 if(getRank(x, y, mid, 1, n, 1) + 1 <= z) {
408                     l = mid;
409                 }
410                 else {
411                     r = mid - 1;
412                 }
413             }
414             printf("%d\n", r);
415         }
416         else if(f == 3) {
417             change(x, y, 1, n, 1);
418         }
419         else if(f == 4) {
420             scanf("%d", &z);
421             int t = getPre(x, y, z, 1, n, 1);
422             printf("%d\n", t);
423         }
424         else if(f == 5) {
425             scanf("%d", &z);
426             int t = getNex(x, y, z, 1, n, 1);
427             printf("%d\n", t);
428         }
429     }
430
431     return 0;
432 }
AC代码

posted @ 2019-01-17 09:19  huyufeifei  阅读(...)  评论(...编辑  收藏