bzoj2648 SJY摆棋子

题目链接

思路

\(KD-tree\)模板题

代码

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
#define ls TR[rt].ch[0]
#define rs TR[rt].ch[1]
const int N = 1000000 + 100,INF = 1e9;
ll read() {
	ll x=0,f=1;char c=getchar();
	while(c<'0'||c>'9') {
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9') {
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}
struct node {
	int ch[2],d[2],mx[2],mn[2];
}TR[N],TMP,a[N];
int n,m;
int ans,root;
int fx;
bool cmp(const node &A,const node &B) {
	return A.d[fx] < B.d[fx];
}
void up(int rt) {
	for(int i = 0;i <= 1;++i) {
		if(ls) TR[rt].mn[i] = min(TR[rt].mn[i],TR[ls].mn[i]),
			TR[rt].mx[i] = max(TR[rt].mx[i],TR[ls].mx[i]);
		if(rs) TR[rt].mn[i] = min(TR[rt].mn[i],TR[rs].mn[i]),
			TR[rt].mx[i] = max(TR[rt].mx[i],TR[rs].mx[i]);
	}
}
int build(int l,int r,int now) {
	fx = now;
	int mid = (l + r) >> 1;
	nth_element(a + l,a + mid,a + r + 1,cmp);
	TR[mid] = a[mid];
	int rt = mid;
	for(int i = 0;i <= 1;++i) TR[mid].mn[i] = TR[mid].mx[i] = TR[mid].d[i];
		if(l < mid) ls = build(l,mid - 1,now ^ 1);
		if(r > mid) rs = build(mid + 1,r,now ^ 1);
		up(mid);
		return mid;
}
void insert(int rt,int now) {
	if(TMP.d[now] >= TR[rt].d[now]) {
		if(rs) insert(rs,now ^ 1);
		else {
			rs = ++n;
			TR[n] = TMP;
			for(int i = 0;i <= 1;++i) TR[n].mn[i] = TR[n].mx[i] = TR[n].d[i];
		}
	}
	else {
		if(ls) insert(ls,now ^ 1);
		else {
			ls = ++n;
			TR[n] = TMP;
			for(int i = 0;i <= 1;++i) TR[n].mn[i] = TR[n].mx[i] = TR[n].d[i];
		}
	}
	up(rt);
}
int dis(const node &A,const node &B) {
	return abs(A.d[0] - B.d[0]) + abs(A.d[1] - B.d[1]);
}
int get(node A,node B) {
	int ret = 0;
	for(int i = 0;i <= 1;++i) ret += max(0,A.mn[i] - B.d[i]);
	for(int i = 0;i <= 1;++i) ret += max(0,B.d[i] - A.mx[i]);
	return ret;
}
void query(int rt,int now) {
	int d = dis(TR[rt],TMP),dl = INF,dr = INF;
	ans = min(ans,d);
	if(ls) dl = get(TR[ls],TMP);
	if(rs) dr = get(TR[rs],TMP);
	if(dl < dr) {
		if(dl < ans) query(ls,now ^ 1);
		if(dr < ans) query(rs,now ^ 1);
	}
	else {
		if(dr < ans) query(rs,now ^ 1);
		if(dl < ans) query(ls,now ^ 1);
	}
}
int Query(int x,int y) {
	TMP.d[0] = x;TMP.d[1] = y;
	ans = INF;
	query(root,0);
	return ans;
}
void Insert(int x,int y) {
	TMP.d[0] = x;TMP.d[1] = y;
	insert(root,0);
}
int main() {
	// freopen("2648/17.in","r",stdin);
	n = read(),m = read();
	for(int i = 1;i <= n;++i) {
		a[i].d[0] = read();a[i].d[1] = read();
	}
	root = build(1,n,0);
	for(int i = 1;i <= m;++i) {
		int opt = read(),x = read(),y = read();
		if(opt == 1) Insert(x,y);
		else printf("%d\n",Query(x,y));
	}
	return 0;
}
posted @ 2019-06-13 09:01  wxyww  阅读(74)  评论(0编辑  收藏