1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| const int N = 6e5 + 9; const double Alph = 0.75; const int INF = 0x7fffffff;
struct Pos { int x[2]; }; struct Node { int minx[2], maxx[2], ls, rs, sz; Pos p; };
int n, m, ans, root, cnt, nd; Pos a[N]; Node tr[N]; queue<int> trash;
bool operator <(Pos A, Pos B) { return A.x[nd] < B.x[nd]; }
inline int new_node() { int x; if (trash.empty()) x = ++cnt; else x = trash.front(), trash.pop(); return x; }
inline void push_up(int x) { int ls = tr[x].ls, rs = tr[x].rs; for (int i = 0; i <= 1; ++i) { tr[x].minx[i] = tr[x].maxx[i] = tr[x].p.x[i]; if (ls) tr[x].minx[i] = min(tr[x].minx[i], tr[ls].minx[i]), tr[x].maxx[i] = max(tr[x].maxx[i], tr[ls].maxx[i]); if (rs) tr[x].minx[i] = min(tr[x].minx[i], tr[rs].minx[i]), tr[x].maxx[i] = max(tr[x].maxx[i], tr[rs].maxx[i]); } tr[x].sz = tr[ls].sz + tr[rs].sz + 1; }
int build(int l, int r, int d) { if (l > r) return 0; int x = new_node(), mid = (l + r) >> 1; nd = d, nth_element(a+l, a+mid, a+r+1), tr[x].p = a[mid]; tr[x].ls = build(l, mid-1, d^1), tr[x].rs = build(mid+1, r, d^1); push_up(x); return x; }
void pia(int x, int num) { if (tr[x].ls) pia(tr[x].ls, num); a[num+tr[tr[x].ls].sz+1] = tr[x].p, trash.push(x); if (tr[x].rs) pia(tr[x].rs, num + tr[tr[x].ls].sz + 1); }
inline void check(int &x, int d) { if (Alph * tr[x].sz < tr[tr[x].ls].sz || Alph * tr[x].sz < tr[tr[x].rs].sz) pia(x, 0), x = build(1, tr[x].sz, d); }
void insert(Pos tp, int &x, int d) { if (!x) { x = new_node(), tr[x].p = tp, tr[x].ls = tr[x].rs = 0, push_up(x); return; } if (tp.x[d] <= tr[x].p.x[d]) insert(tp, tr[x].ls, d^1); else insert(tp, tr[x].rs, d^1); push_up(x), check(x, d); }
|