bzoj2648/2716 SJY摆棋子

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2648

http://www.lydsy.com/JudgeOnline/problem.php?id=2716

【题解】

直接上kdtree

用查询的最近最远点的那种写法。

估价在上一篇博客。

还不知道过了吗真是傻逼还有人卡评测我日

重构的BLOCK选在最多点数的1/10左右即可。。

成功垫底。

我真是傻逼RE了好几发

build后面和rebuild都要ret。。。

# include <stdio.h>
# include <string.h>
# include <iostream> 
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 1e6 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

inline void gmin(int &x, int y) {if(x > y) x = y;}
inline void gmax(int &x, int y) {if(x < y) x = y;}

int D;
struct node {
    int d[2], mi[2], mx[2], l, r;
    friend bool operator == (node a, node b) {
        return a.d[0] == b.d[0] && a.d[1] == b.d[1];
    }
    friend bool operator < (node a, node b) {
        return a.d[D] < b.d[D];
    }
}a[M], t[M];

# define ls T[x].l
# define rs T[x].r

int n, m;

node tmp;
struct KDT {
    node T[M];
    int siz, rt;
    inline void set() {
        rt = siz = 0;
    }
    inline int getdist(int x, int X, int Y) {
        return max(T[x].mi[0]-X, 0) + max(X-T[x].mx[0], 0) + max(T[x].mi[1]-Y, 0) + max(Y-T[x].mx[1], 0);
    }
    inline void up(int x) {
        for (int i=0; i<2; ++i) {
            T[x].mi[i] = T[x].mx[i] = T[x].d[i];
            if(ls) gmin(T[x].mi[i], T[ls].mi[i]);
            if(rs) gmin(T[x].mi[i], T[rs].mi[i]);
            if(ls) gmax(T[x].mx[i], T[ls].mx[i]);
            if(rs) gmax(T[x].mx[i], T[rs].mx[i]);
        }
    }
            
    inline int build(int l, int r, int d) {
        if(l>r) return 0;
        int mid = l+r>>1;
        D = d; nth_element(t+l, t+mid, t+r+1);
//        printf("mid = %d\n", mid);
        T[mid] = t[mid];
        T[mid].l = build(l, mid-1, d^1);
        T[mid].r = build(mid+1, r, d^1);
        up(mid);
//        printf("%d [%d,%d], [%d,%d], (%d, %d)\n", mid, T[mid].mi[0], T[mid].mx[0], T[mid].mi[1], T[mid].mx[1], T[mid].d[0], T[mid].d[1]);
//        printf("   ls = %d, rs = %d\n", T[mid].l, T[mid].r); 
        return mid;
    }
    
    inline void insert(int &x, int d) {
        if(!x) {
            x = ++siz;
            for (int i=0; i<2; ++i)
                T[x].d[i] = T[x].mi[i] = T[x].mx[i] = tmp.d[i];
            T[x].l = 0, T[x].r = 0;
        }
        if(tmp == T[x]) return ;
        if(tmp.d[d] < T[x].d[d]) insert(ls, d^1);
        else insert(rs, d^1);
        up(x);
    }
    
    int ans;
    inline void query(int x, int X, int Y) {
        if(!x) return;
        int tmp = abs(T[x].d[0]-X) + abs(T[x].d[1]-Y), d[2];
        if(ls) d[0] = getdist(ls, X, Y); else d[0] = 2147483647;
        if(rs) d[1] = getdist(rs, X, Y); else d[1] = 2147483647; 
        gmin(ans, tmp);
        if(d[0] < d[1]) {
            if(d[0] < ans) query(ls, X, Y);
            if(d[1] < ans) query(rs, X, Y);
        } else {
            if(d[1] < ans) query(rs, X, Y);
            if(d[0] < ans) query(ls, X, Y);
        }
    }
    
    inline int query(int X, int Y) {
        ans = 2147483647;
        query(rt, X, Y);
        return ans;
    }
    
    inline int rebuild(int l, int r, int d) {
        if(l>r) return 0;
        int mid = l+r>>1;
        D = d; nth_element(t+l, t+mid, t+r+1);
        T[mid] = t[mid];
        T[mid].l = rebuild(l, mid-1, d^1);
        T[mid].r = rebuild(mid+1, r, d^1);
        up(mid);
        return mid;
    }
}T; 

int REBUILD_SIZE = 100000;

inline bool cmp(node a, node b) {
    return a.d[0] < b.d[0] || (a.d[0] == b.d[0] && a.d[1] < b.d[1]);
}

int main() {
//    freopen("bzoj2648.in", "r", stdin);
//    freopen("bzoj2648.out", "w", stdout);
    scanf("%d%d", &n, &m);
    for (int i=1; i<=n; ++i) scanf("%d%d", &a[i].d[0], &a[i].d[1]);
    sort(a+1, a+n+1, cmp);
    int tn = 0;
    t[++tn] = a[1];
    for (int i=2; i<=n; ++i) 
         if(!(a[i] == a[i-1])) t[++tn] = a[i];
    n = tn; REBUILD_SIZE += n; T.siz = n;
    T.rt = T.build(1, n, 0);
    int opt, x, y;
    for (int test = 1; test <= m; ++test) {
        scanf("%d%d%d", &opt, &x, &y);
        if(opt == 1) {
            tmp.d[0] = x, tmp.d[1] = y;
            T.insert(T.rt, 0);
            if(T.siz == REBUILD_SIZE) {
                for (int i=1; i<=T.siz; ++i) t[i] = T.T[i];
                T.rt = T.rebuild(1, T.siz, 0);
                REBUILD_SIZE += 100000;
            }
        } else {
            printf("%d\n", T.query(x, y));
        }
//        cerr << "ok test = " << test << endl;
    }
    return 0;
}
View Code

 

posted @ 2017-05-05 09:59  Galaxies  阅读(255)  评论(0编辑  收藏  举报