1. 程式人生 > >[BZOJ 3224] 普通平衡樹 非旋Treap

[BZOJ 3224] 普通平衡樹 非旋Treap

查詢 getchar printf ++ return type clas else rank

題意

  維護一個多重集合 $S$ , 支持:

    ① 插入一個數 $w$ .

    ② 刪除一個數 $w$ .

    ③ 查詢 $w$ 在集合中的排名.

    ④ 查詢集合中排名第 $r$ 的數.

    ⑤ 求集合中 $w$ 的前驅.

    ⑥ 求集合中 $w$ 的後繼.

  $N \le 100000$ .

小結

  要總結一些常見的寫法和想法, 減小實現時的復雜度.

實現

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>

#define
F(i, a, b) for (register int i = (a); i <= (b); i++) const int N = 100005; int n; int rt, tot, c[N][2], siz[N], fix[N], key[N]; struct D { int c[2]; }; inline int rd(void) { int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -1; int x = 0; for (; isdigit(c); c = getchar()) x = x*10
+c-0; return x*f; } inline void Pushup(int x) { siz[x] = siz[c[x][0]] + siz[c[x][1]] + 1; } inline int Merge(int x, int y) { if (!x || !y) return x+y; if (fix[x] < fix[y]) { c[x][1] = Merge(c[x][1], y); Pushup(x); return x; } else { c[y][0] = Merge(x, c[y][0
]); Pushup(y); return y; } } inline D Split(int x, int k) { if (!x) return D(); if (key[x] > k) { D t = Split(c[x][0], k); c[x][0] = t.c[1], Pushup(x); t.c[1] = x; return t; } else { D t = Split(c[x][1], k); c[x][1] = t.c[0], Pushup(x); t.c[0] = x; return t; } } inline D Split_r(int x, int k) { if (!x) return D(); if (siz[c[x][0]] + 1 > k) { D t = Split_r(c[x][0], k); c[x][0] = t.c[1], Pushup(x); t.c[1] = x; return t; } else { D t = Split_r(c[x][1], k-siz[c[x][0]]-1); c[x][1] = t.c[0], Pushup(x); t.c[0] = x; return t; } } inline int Newnode(int w) { return siz[++tot] = 1, fix[tot] = rand(), key[tot] = w, tot; } inline void Insert(int w) { int x = Newnode(w); D t = Split(rt, w); rt = Merge(Merge(t.c[0], x), t.c[1]); } inline void Delete(int w) { //It‘s guaranteed that w exists! D t = Split(rt, w-1); D tx = Split_r(t.c[1], 1); rt = Merge(t.c[0], tx.c[1]); } inline int Get(int w) { D t = Split(rt, w-1); int res = siz[t.c[0]] + 1; rt = Merge(t.c[0], t.c[1]); return res; } inline int Rank(int k) { D t = Split_r(rt, k-1); D tx = Split_r(t.c[1], 1); int res = key[tx.c[0]]; rt = Merge(t.c[0], Merge(tx.c[0], tx.c[1])); return res; } inline int Pre(int w) { D t = Split(rt, w-1); D tx = Split_r(t.c[0], siz[t.c[0]]-1); int res = key[tx.c[1]]; rt = Merge(Merge(tx.c[0], tx.c[1]), t.c[1]); return res; } inline int Nxt(int w) { D t = Split(rt, w); D tx = Split_r(t.c[1], 1); int res = key[tx.c[0]]; rt = Merge(t.c[0], Merge(tx.c[0], tx.c[1])); return res; } int main(void) { #ifndef ONLINE_JUDGE freopen("bzoj3224.in", "r", stdin); freopen("bzoj3224.out", "w", stdout); #endif n = rd(); F(i, 1, n) { int k = rd(), x = rd(); if (k == 1) Insert(x); else if (k == 2) Delete(x); else if (k == 3) printf("%d\n", Get(x)); else if (k == 4) printf("%d\n", Rank(x)); else if (k == 5) printf("%d\n", Pre(x)); else printf("%d\n", Nxt(x)); } return 0; }

[BZOJ 3224] 普通平衡樹 非旋Treap