# bzoj2648/2716 SJY摆棋子

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

【题解】

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  阅读(240)  评论(0编辑  收藏  举报