【BZOJ2716】【Violet 3】天使玩偶

【题目链接】

【思路要点】

  • 补档博客,无题解。

【代码】

#include<bits/stdc++.h>
using namespace std;
#define MAXN	1000005
#define INF	1e9
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
struct point {int x[2]; } p[MAXN], q[MAXN];
bool querytype[MAXN];
int cmptype;
bool operator == (point a, point b) {
	return a.x[0] == b.x[0] && a.x[1] == b.x[1];
}
bool cmp(point a, point b) {
	return a.x[cmptype] < b.x[cmptype] || a.x[cmptype] == b.x[cmptype] && a.x[cmptype ^ 1] < b.x[cmptype ^ 1];
}
void chkmax(int &x, int y) {
	x = max(x, y);
}
void chkmin(int &x, int y) {
	x = min(x, y);
}
struct KD_Tree {
	struct Node {
		bool active;
		int lc, rc, type;
		point pos, L, R;
	} a[MAXN];
	int n, root, size, nowans;
	point now;
	void update(int root) {
		if (a[root].active) {
			a[root].L = a[root].pos;
			a[root].R = a[root].pos;
		} else {
			a[root].L.x[0] = INF;
			a[root].L.x[1] = INF;
			a[root].R.x[0] = -INF;
			a[root].R.x[1] = -INF;
		}
		if (a[root].lc) {
			int tmp = a[root].lc;
			chkmin(a[root].L.x[0], a[tmp].L.x[0]);
			chkmin(a[root].L.x[1], a[tmp].L.x[1]);
			chkmax(a[root].R.x[0], a[tmp].R.x[0]);
			chkmax(a[root].R.x[1], a[tmp].R.x[1]);
		}
		if (a[root].rc) {
			int tmp = a[root].rc;
			chkmin(a[root].L.x[0], a[tmp].L.x[0]);
			chkmin(a[root].L.x[1], a[tmp].L.x[1]);
			chkmax(a[root].R.x[0], a[tmp].R.x[0]);
			chkmax(a[root].R.x[1], a[tmp].R.x[1]);
		}
	}
	void build(int root, int l, int r, int t) {
		a[root].active = false;
		if (l == r) {
			a[root].pos = p[l];
			a[root].L.x[0] = INF;
			a[root].L.x[1] = INF;
			a[root].R.x[0] = -INF;
			a[root].R.x[1] = -INF;
			a[root].type = t;
			return;
		}
		int mid = (l + r) / 2;
		cmptype = t;
		nth_element(p + l, p + mid, p + r + 1, cmp);
		a[root].pos = p[mid];
		a[root].type = t;
		if (mid > l) {
			a[root].lc = ++size;
			build(size, l, mid - 1, t ^ 1);
		}
		if (mid < r) {
			a[root].rc = ++size;
			build(size, mid + 1, r, t ^ 1);
		}
		update(root);
	}
	void init(int x) {
		n = x; root = size = 1;
		build(size, 1, n, 0);
	}
	int dist(int root, point now) {
		return abs(a[root].pos.x[0] - now.x[0]) + abs(a[root].pos.x[1] - now.x[1]);
	}
	int distmin(int root, point now) {
		if (root == 0 || a[root].L.x[0] == INF) return INF;
		int ans = 0;
		if (now.x[0] <= a[root].L.x[0]) ans += a[root].L.x[0] - now.x[0];
		if (now.x[0] >= a[root].R.x[0]) ans += now.x[0] - a[root].R.x[0];
		if (now.x[1] <= a[root].L.x[1]) ans += a[root].L.x[1] - now.x[1];
		if (now.x[1] >= a[root].R.x[1]) ans += now.x[1] - a[root].R.x[1];
		return ans;
	}
	void querymin(int root) {
		if (a[root].active) {
			int d = dist(root, now);
			chkmin(nowans, d);
		}
		int ld = distmin(a[root].lc, now);
		int rd = distmin(a[root].rc, now);
		if (ld <= rd) {
			if (a[root].lc && ld < nowans) querymin(a[root].lc);
			if (a[root].rc && rd < nowans) querymin(a[root].rc);
		} else {
			if (a[root].rc && rd < nowans) querymin(a[root].rc);
			if (a[root].lc && ld < nowans) querymin(a[root].lc);
		}
	}
	int Querymin(point x) {
		now = x; nowans = INF;
		querymin(root);
		return nowans;
	}
	void insert(int root, int t) {
		if (a[root].pos == now) {
			a[root].active = true;
			update(root);
			return;
		}
		cmptype = t;
		if (cmp(now, a[root].pos)) insert(a[root].lc, t ^ 1);
		else insert(a[root].rc, t ^ 1);
		update(root);
	}
	void Insert(point x) {
		now = x;
		insert(root, 0);
	}
} KDT;
int main() {
	int n, m;
	read(n), read(m);
	for (int i = 1; i <= n; i++) {
		read(p[i].x[0]), read(p[i].x[1]);
		q[i] = p[i];
	}
	int tn = n;
	for (int i = 1; i <= m; i++) {
		int opt; read(opt);
		read(q[n + i].x[0]), read(q[n + i].x[1]);
		if (opt == 1) {
			querytype[i] = true;
			p[++tn] = q[n + i];
		} else querytype[i] = false;
	}
	KDT.init(tn);
	for (int i = 1; i <= n; i++)
		KDT.Insert(q[i]);
	for (int i = 1; i <= m; i++)
		if (querytype[i]) KDT.Insert(q[n + i]);
		else printf("%d\n", KDT.Querymin(q[n + i]));
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BZOJ 2908 题目是一个数据下载任务。这个任务要求下载指定的数据文件,并统计文件中小于等于给定整数的数字个数。 为了完成这个任务,首先需要选择一个合适的网址来下载文件。我们可以使用一个网络爬虫库,如Python中的Requests库,来帮助我们完成文件下载的操作。 首先,我们需要使用Requests库中的get()方法来访问目标网址,并将目标文件下载到我们的本地计算机中。可以使用以下代码实现文件下载: ```python import requests url = '目标文件的网址' response = requests.get(url) with open('本地保存文件的路径', 'wb') as file: file.write(response.content) ``` 下载完成后,我们可以使用Python内置的open()函数打开已下载的文件,并按行读取文件内容。可以使用以下代码实现文件内容读取: ```python count = 0 with open('本地保存文件的路径', 'r') as file: for line in file: # 在这里实现对每一行数据的判断 # 如果小于等于给定整数,count 加 1 # 否则,不进行任何操作 ``` 在每一行的处理过程中,我们可以使用split()方法将一行数据分割成多个字符串,并使用int()函数将其转换为整数。然后,我们可以将该整数与给定整数进行比较,以判断是否小于等于给定整数。 最后,我们可以将统计结果打印出来,以满足题目的要求。 综上所述,以上是关于解决 BZOJ 2908 数据下载任务的简要步骤和代码实现。 希望对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值