【LG4148】簡單題
阿新 • • 發佈:2018-12-30
【LG4148】簡單題
題面
題解
\(kdt\)模板題呀。。。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; inline int gi() { register int data = 0, w = 1; register char ch = 0; while (!isdigit(ch) && ch != '-') ch = getchar(); if (ch == '-') w = -1, ch = getchar(); while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar(); return w * data; } void chkmin(int &x, int y) { if (x > y) x = y; } void chkmax(int &x, int y) { if (x < y) x = y; } const int MAX_N = 4e5 + 5; const double alpha = 0.75; const int INF = 1e9; struct Point { int x[2], w; } p[MAX_N]; struct Node { int mn[2], mx[2]; int ls, rs, sum, size; Point tp; } t[MAX_N]; int ans, N, M, WD, cur, top, rt, rub[MAX_N]; inline bool operator < (const Point &l, const Point &r) { return l.x[WD] < r.x[WD]; } inline int newnode() { if (top) return rub[top--]; else return ++cur; } void pushup(int o) { int ls = t[o].ls, rs = t[o].rs; for (int i = 0; i <= 1; i++) { t[o].mn[i] = t[o].mx[i] = t[o].tp.x[i]; if (ls) chkmin(t[o].mn[i], t[ls].mn[i]), chkmax(t[o].mx[i], t[ls].mx[i]); if (rs) chkmin(t[o].mn[i], t[rs].mn[i]), chkmax(t[o].mx[i], t[rs].mx[i]); } t[o].sum = t[ls].sum + t[rs].sum + t[o].tp.w, t[o].size = t[ls].size + t[rs].size + 1; } int build(int l, int r, int wd) { if (l > r) return 0; int mid = (l + r) >> 1, o = newnode(); WD = wd, nth_element(&p[l], &p[mid], &p[r + 1]), t[o].tp = p[mid]; t[o].ls = build(l, mid - 1, wd ^ 1), t[o].rs = build(mid + 1, r, wd ^ 1); return pushup(o), o; } void pia(int o, int num) { if (t[o].ls) pia(t[o].ls, num); p[num + t[t[o].ls].size + 1] = t[o].tp, rub[++top] = o; if (t[o].rs) pia(t[o].rs, num + t[t[o].ls].size + 1); } void check(int &o, int wd) { if (alpha * t[o].size < t[t[o].ls].size || alpha * t[o].size < t[t[o].rs].size) pia(o, 0), o = build(1, t[o].size, wd); } void insert(int &o, int wd, Point tmp) { if (!o) return (void)(o = newnode(), t[o].ls = t[o].rs = 0, t[o].tp = tmp, pushup(o)); if (tmp.x[wd] <= t[o].tp.x[wd]) insert(t[o].ls, wd ^ 1, tmp); else insert(t[o].rs, wd ^ 1, tmp); pushup(o), check(o, wd); } bool inner(int x1, int y1, int x2, int y2, int X1, int Y1, int X2, int Y2) { return (X1 >= x1 && X2 <= x2 && Y1 >= y1 && Y2 <= y2); } int outter(int x1, int y1, int x2, int y2, int X1, int Y1, int X2, int Y2) { return (x1 > X2 || x2 < X1 || y1 > Y2 || y2 < Y1); } int query(int o, int x1, int y1, int x2, int y2) { if (!o) return 0; int res = 0; if (inner(x1, y1, x2, y2, t[o].mn[0], t[o].mn[1], t[o].mx[0], t[o].mx[1])) return t[o].sum; if (outter(x1, y1, x2, y2, t[o].mn[0], t[o].mn[1], t[o].mx[0], t[o].mx[1])) return 0; if (inner(x1, y1, x2, y2, t[o].tp.x[0], t[o].tp.x[1], t[o].tp.x[0], t[o].tp.x[1])) res += t[o].tp.w; res += query(t[o].ls, x1, y1, x2, y2) + query(t[o].rs, x1, y1, x2, y2); return res; } int main () { N = gi(); for ( ; ; ) { int op = gi(); if (op == 3) break; if (op == 1) insert(rt, 0, (Point){gi()^ ans, gi() ^ ans, gi() ^ ans}); else { int x1 = gi() ^ ans, y1 = gi() ^ ans, x2 = gi() ^ ans, y2 = gi() ^ ans; printf("%d\n", ans = query(rt, x1, y1, x2, y2)); } } return 0; }