二次联通门 : LibreOJ #104. 普通平衡树
#include <cstdio> #include <iostream> #include <algorithm> const int BUF = 12312323; char Buf[BUF], *buf = Buf; inline void read (int &now) { bool temp = false; for (now = 0; !isdigit (*buf); ++ buf) if (*buf == '-') temp = true; for (; isdigit (*buf); now = now *10 + *buf - '0', ++ buf); if (temp) now = -now; } struct T_D { T_D *L, *R; int key, r, s; inline void Updata () { s = 1 + (L ? L->s : 0) + (R ? R->s : 0); } }; #define Max 1231231 struct D { T_D *x, *y; D () {} D (T_D *_x, T_D *_y) : x (_x), y (_y) {} }; class Fhq_Treap { private : T_D poor[Max], *Ta, *Root; inline T_D *New (int _x) { T_D *now = ++ Ta; now->r = rand (), now->key = _x; now->s = 1, now->L = now->R = NULL; return now; } D Split (T_D *now, int k) { if (now == NULL) return D (NULL, NULL); D res; if ((now->L ? now->L->s : 0) >= k) { res = Split (now->L, k); now->L = res.y, now->Updata (); res.y = now; } else { res = Split (now->R, k - (now->L ? now->L->s : 0) - 1); now->R = res.x, now->Updata (); res.x = now; } return res; } T_D *Merge (T_D *A, T_D *B) { if (A == NULL) return B; if (B == NULL) return A; if (A->r < B->r) { A->R = Merge (A->R, B); A->Updata (); return A; } else { B->L = Merge (A, B->L); B->Updata (); return B; } } int Get_rank (T_D *now, int k) { if (now == NULL) return 0; return k <= now->key ? Get_rank (now->L, k) : (Get_rank (now->R, k) + (now->L ? now->L->s : 0) + 1); } public : Fhq_Treap () { Ta = poor; } inline int Get_rank (int k) { return Get_rank (Root, k) + 1; } int Find_kth (int k) { D x = Split (Root, k - 1); D y = Split (x.y, 1); T_D *res = y.x; Root = Merge (Merge (x.x, res), y.y); return res->key; } void Insert (int key) { int k = Get_rank (Root, key); D x = Split (Root, k); T_D *now = New (key); Root = Merge (Merge (x.x, now), x.y); } void Delete (int key) { int k = Get_rank (Root, key); D x = Split (Root, k); D y = Split (x.y, 1); Root = Merge (x.x, y.y); } int Find_Pre (int key) { int k = Get_rank (Root, key); D x = Split (Root, k - 1); D y = Split (x.y, 1); T_D *res = y.x; Root = Merge (Merge (x.x, res), y.y); return res->key; } int Find_Suc (int key) { int k = Get_rank (Root, key + 1); D x = Split (Root, k); D y = Split (x.y, 1); T_D *res = y.x; Root = Merge (Merge (x.x, res), y.y); return res->key; } }; Fhq_Treap Tree; int Main () { fread (buf, 1, BUF, stdin); int N, M; register int i; read (N); int x, type; for (i = 1; i <= N; ++ i) { read (type), read (x); if (type == 1) Tree.Insert (x); else if (type == 2) Tree.Delete (x); else if (type == 3) printf ("%d ", Tree.Get_rank (x)); else if (type == 4) printf ("%d ", Tree.Find_kth (x)); else if (type == 5) printf ("%d ", Tree.Find_Pre (x)); else printf ("%d ", Tree.Find_Suc (x)); } return 0; } int ZlycerQan = Main (); int main (int argc, char *argv[]) {;}