[BZOJ2716][Violet 3]天使玩偶 && kdtree

来源:互联网 发布:北京淘宝供货商 编辑:程序博客网 时间:2024/05/01 17:23

存模板

#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<queue>#define SF scanf#define PF printf#define mp make_pair#define sqr(x) ((x)*(x))#define max(a, b) ((a) > (b) ? (a) : (b))#define min(a, b) ((a) < (b) ? (a) : (b))using namespace std;typedef long long LL;const int MAXN = 500000;const int INF = 0x3f3f3f3f;struct Node {    int d[2], mn[2], mx[2];    int l, r;    int operator [] (int x) const { return d[x]; }    int & operator [] (int x) { return d[x]; }    Node (int x = 0, int y = 0) {        l = r = 0; d[0] = x; d[1] = y;    }} A[MAXN+10];int direction;bool operator < (const Node &a, const Node &b) {    return a[direction] < b[direction];}inline LL dis(const Node &a, const Node &b) {    return abs(a[0]-b[0])+abs(a[1]-b[1]);}struct kd_Tree {    int ans;    int ncnt, root;    Node t[MAXN*2+10], T;    inline void up(int x) {        Node &u = t[x];        Node l = t[u.l], r = t[u.r];        for(int i = 0; i < 2; i++) {            if(u.l) u.mn[i] = min(u.mn[i], l.mn[i]), u.mx[i] = max(u.mx[i], l.mx[i]);            if(u.r) u.mn[i] = min(u.mn[i], r.mn[i]), u.mx[i] = max(u.mx[i], r.mx[i]);        }    }    int build(int l, int r, int dir, Node *p) {        direction = dir;        int mid = (l+r) >> 1;        nth_element(p+l, p+mid, p+r+1);        t[mid] = p[mid];        for(int i = 0; i < 2; i++)            t[mid].mn[i] = t[mid].mx[i] = t[mid][i];        if(l < mid) t[mid].l = build(l, mid-1, dir^1, p);        if(r > mid) t[mid].r = build(mid+1, r, dir^1, p);        up(mid);        return mid;    }    inline void ins(int k, int dir) {        Node &u = t[k];        if(T[dir] >= u[dir]) {            if(u.r) ins(u.r, dir^1);            else {                u.r = ++ncnt; t[ncnt] = T;                for(int i = 0; i < 2; i++)                    t[ncnt].mn[i] = t[ncnt].mx[i] = t[ncnt][i];            }        }        else {            if(u.l) ins(u.l, dir^1);            else {                u.l = ++ncnt; t[ncnt] = T;                for(int i = 0; i < 2; i++)                    t[ncnt].mn[i] = t[ncnt].mx[i] = t[ncnt][i];            }        }        up(k);    }    inline LL get_dis(int k, const Node &p) {        LL ret = 0;        for(int i = 0; i < 2; i++) ret += max(0, p[i] - t[k].mx[i]);        for(int i = 0; i < 2; i++) ret += max(0, t[k].mn[i] - p[i]);        return ret;    }    inline void query(int x, int dir) {        Node &u = t[x];        int d = dis(u, T);        int dl = INF, dr = INF;        ans = min(ans, d);        if(u.l) dl = get_dis(u.l, T);        if(u.r) dr = get_dis(u.r, T);        if(dl < dr) {            if(dl < ans) query(u.l, dir^1);            if(dr < ans) query(u.r, dir^1);        }        else {            if(dr < ans) query(u.r, dir^1);            if(dl < ans) query(u.l, dir^1);        }    }    inline void ins(const Node &p) {        T = p; ins(root, 0);    }    inline int query(const Node &p) {        ans = INF; T = p; query(root, 0);        return ans;    }} kd;int n, m, x;int main() {    SF("%d%d", &n, &m);    for(int i = 1; i <= n; i++) SF("%d%d", &A[i][0], &A[i][1]);kd.ncnt = n;    kd.root = kd.build(1, n, 0, A);    for(int i = 1; i <= m; i++) {        int op, x, y;        SF("%d%d%d", &op, &x, &y);        if(op == 1) kd.ins(Node(x, y));        else PF("%d\n", kd.query(Node(x, y)));    }}


0 0
原创粉丝点击