二次联通门 : luogu P3369 【模板】普通平衡树(Treap/SBT)
闲的没事,把各种平衡树都写写
比较比较。。。
下面是替罪羊树
#include <cstdio> #include <vector> #define Max_ 100010 #define Inline __attri\ bute__( ( optimize( "-O2" ) ) ) Inline void read (int &now) { register char word = getchar (); bool temp = false; for (now = 0; word < ‘0‘ || word > ‘9‘; word = getchar ()) if (word == ‘-‘) temp = true; for (; word >= ‘0‘ && word <= ‘9‘; now = now * 10 + word - ‘0‘, word = getchar ()); if (temp) now = -now; } const double alpha = 0.63; int N; struct G_D { G_D *child[2]; int key; int size, total; bool is_exist; inline void Up () { this->size = this->child[0]->size + this->child[1]->size + is_exist; this->total = this->child[0]->total + this->child[1]->total + 1; } inline bool is_rebuild () { return ((this->child[0]->total > this->total * alpha + 5) || (this->child[1]->total > this->total * alpha + 5)); } }; class Scapegoat_Tree_Type { private : G_D poor_mem[Max_]; G_D *Root, *Tail, *null; G_D *reuse[Max_]; int Reuse_top; Inline G_D *New_Node (int key) { G_D *now = Reuse_top ? reuse[-- Reuse_top] : Tail ++; now->child[0] = now->child[1] = null; now->size = now->total = 1; now->is_exist = true; now->key = key; return now; } Inline void Travel (G_D *now, std :: vector <G_D *> &line) { if (now == null) return ; Travel (now->child[0], line); if (now->is_exist) line.push_back (now); else reuse[Reuse_top ++] = now; Travel (now->child[1], line); } Inline G_D *Divide (std :: vector <G_D *> &line, int l, int r) { if (l >= r) return null; int Mid = (l + r) >> 1; G_D *now = line[Mid]; now->child[0] = Divide (line, l, Mid); now->child[1] = Divide (line, Mid + 1, r); now->Up (); return now; } Inline void Re_Build (G_D *&now) { static std :: vector <G_D *> line; line.clear (); Travel (now, line); now = Divide (line, 0, line.size ()); } Inline G_D **Insert (G_D *&now, int key) { if (now == null) { now = New_Node (key); return &null; } else { now->size ++; now->total ++; G_D **res = Insert (now->child[key >= now->key], key); if (now->is_rebuild ()) res = &now; return res; } } Inline void Erase (G_D *now, int pos) { now->size --; int res = now->child[0]->size + now->is_exist; if (now->is_exist && pos == res) { now->is_exist = false; return ; } else { if (pos <= res) Erase (now->child[0], pos); else Erase (now->child[1], pos - res); } } public : Scapegoat_Tree_Type () { Tail = poor_mem; null = Tail ++; null->child[0] = null->child[1] = null; null->total = null->size = null->key = 0; Root = null; Reuse_top = 0; } Inline void Insert (int key) { G_D **now = this->Insert (Root, key); if (*now != null) Re_Build (*now); } Inline int Get_Rank (int key) { G_D *now = Root; register int Answer = 1; for (; now != null; ) { if (now->key >= key) now = now->child[0]; else { Answer += now->child[0]->size + now->is_exist; now = now->child[1]; } } return Answer; } Inline int Get_kth_number (int k) { int Count = 0; for (G_D *now = Root; now != null; ) { if (now->child[0]->size + 1 == k && now->is_exist) return now->key; else if (now->child[0]->size >= k) now = now->child[0]; else { k -= now->child[0]->size + now->is_exist; now = now->child[1]; } } } Inline void Erase (int pos) { Erase (Root, Get_Rank (pos)); if (Root->size < alpha * Root->total) Re_Build (Root); } }; Scapegoat_Tree_Type Tree; int M; int main (int argc, char *argv[]) { read (M); for (int type, x; M --; ) { read (type); read (x); switch (type) { case 1: Tree.Insert (x); break; case 2: Tree.Erase (x); break; case 3: printf ("%d\n", Tree.Get_Rank (x)); break; case 4: printf ("%d\n", Tree.Get_kth_number (x)); break; case 5: printf ("%d\n", Tree.Get_kth_number (Tree.Get_Rank (x) - 1)); break; case 6: printf ("%d\n", Tree.Get_kth_number (Tree.Get_Rank (x + 1))); break; } } return 0; }
时间: 2024-10-02 06:16:45