treap模板
阿新 • • 發佈:2017-12-24
-cp fine min -- fde 模板 del memset etc
#include <bits/stdc++.h> #define For(i, l, r) for(int i = (l), _end_ = (int)(r); i <= _end_; ++i) #define Fordown(i, r, l) for(int i = (r), _end_ = (int)(l); i >= _end_; --i) #define Set(a, v) memset(a, v, sizeof(a)) using namespace std; inline bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;} inline bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;} inline int read() { int x = 0, fh = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar() ) if (ch == ‘-‘) fh = -1; for (; isdigit(ch); ch = getchar() ) x = (x<<1) + (x<<3) + (ch ^ ‘0‘); return x * fh; } void File() { #ifdef zjp_shadow freopen ("P3369.in", "r", stdin); freopen ("P3369.out", "w", stdout); #endif } const int maxnode = 2e6 + 1e3; int ch[maxnode][2]; int val[maxnode]; int cnt[maxnode], cnt_sum[maxnode]; int prio[maxnode]; struct Treap{ inline int new_node(int val_) { static int len = 0, u; u = ++ len; ch[u][0] = ch[u][1] = 0; val[u] = val_; cnt_sum[u] = cnt[u] = 1; prio[u] = rand() ; return u; } // inline void push_up(int u) { #define push_up(u) cnt_sum[(u)] = cnt_sum[ch[(u)][0]] + cnt_sum[ch[(u)][1]] + cnt[(u)]; // } inline void rotate(int &u, int d) { int v = ch[u][d]; ch[u][d] = ch[v][d ^ 1]; ch[v][d ^ 1] = u; push_up(u); push_up(v); u = v; } void Out(int u) { if (!u) return ; Out (ch[u][0]); printf ("%d ", val[u]); Out (ch[u][1]); } void Insert(int &u, int val_) { if (!u) { u = new_node(val_); return ; } if (val[u] == val_) ++ cnt[u]; else { int d = (val_ > val[u]); Insert(ch[u][d], val_); if (prio[ch[u][d]] > prio[u]) rotate(u, d); } push_up(u); } void Erase(int &u) { if (!ch[u][0] && !ch[u][1]) { u = 0; return ; } int d = (prio[ch[u][1]] > prio[ch[u][0]]); rotate(u, d); Erase(ch[u][d ^ 1]); push_up(u); } void Delete(int &u, int val_) { if (val[u] == val_) { if (!(-- cnt[u]) ) Erase(u); else push_up(u); return ; } int d = (val_ > val[u]); Delete(ch[u][d], val_); push_up(u); } int Rank(int u, int val_) { if (val[u] == val_) return cnt_sum[ch[u][0]]; int d = (val_ > val[u]); return d * (cnt_sum[ch[u][0]] + cnt[u]) + Rank(ch[u][d], val_); } int Kth(int u, int k) { if (k > cnt_sum[ch[u][0]] && k <= cnt_sum[ch[u][0]] + cnt[u]) return val[u]; int d = (k > cnt_sum[ch[u][0]]); k -= d * (cnt_sum[ch[u][0]] + cnt[u]); return Kth(ch[u][d], k); } int Pre(int u, int val_) { int res = 0; if (!u) return res; if (val[u] < val_) res = val[u]; int d = (val_ > val[u]); return max(res, Pre(ch[u][d], val_) ); } int Suf(int u, int val_) { int res = 0x7f7f7f7f; if (!u) return res; if (val[u] > val_) res = val[u]; int d = (val_ >= val[u]); return min(res, Suf(ch[u][d], val_) ); } }; Treap T; int main () { File(); srand(93799); static int n = read() ; static int root = 0; while (n --) { static int opt, val_; opt = read(); val_ = read(); if (opt == 1) T.Insert(root, val_); if (opt == 2) T.Delete(root, val_); if (opt == 3) printf ("%d\n", T.Rank(root, val_) + 1); if (opt == 4) printf ("%d\n", T.Kth(root, val_) ); if (opt == 5) printf ("%d\n", T.Pre(root, val_) ); if (opt == 6) printf ("%d\n", T.Suf(root, val_) ); } return 0; }
treap模板