【資料結構】無旋Treap
阿新 • • 發佈:2020-09-14
namespace FHQTreap { const int MAXN = 200000 + 5; int ls[MAXN]; int rs[MAXN]; int rd[MAXN]; int sz[MAXN]; int ct; int rt; int va[MAXN]; ll sm[MAXN]; void Init() { rt = 0; ct = 0; va[rt] = 0; sm[rt] = 0LL; } void PushUp(int o) { sz[o] = sz[ls[o]] + sz[rs[o]] + 1; sm[o] = sm[ls[o]] + sm[rs[o]] + va[o]; } void SplitRank(int o, int rk, int &x, int &y) { if(!o) { x = 0; y = 0; } else if(rk <= sz[ls[o]]) { y = o; SplitRank(ls[o], rk, x, ls[o]); PushUp(y); } else { x = o; SplitRank(rs[o], rk - sz[ls[o]] - 1, rs[o], y); PushUp(x); } } int Merge(int x, int y) { if(!x || !y) return x | y; else if(rd[x] < rd[y]) { rs[x] = Merge(rs[x], y); PushUp(x); return x; } else { ls[y] = Merge(x, ls[y]); PushUp(y); return y; } } int NewNode(int v) { int o = ++ct; ls[o] = 0; rs[o] = 0; rd[o] = rand(); sz[o] = 1; va[o] = v; PushUp(o); return o; } int ValAt(int rk) { int o = rt; while(o) { if(sz[ls[o]] >= rk) { o = ls[o]; continue; } else if(sz[ls[o]] + 1 >= rk) break; else { rk -= sz[ls[o]] + 1; o = rs[o]; continue; } } return va[o]; } } using namespace FHQTreap;
這裡提供了ValAt作為二分的典範,事實上平衡樹要維護的東西就是這樣的,不斷在樹上走直到命中某個節點,根據自己的向左走或者向右走的情況,把子樹的資訊統計上來。