【bzoj2648】SJY摆棋子(kdtree)
题意:
二维平面上有若干个点。
现在要维护一种数据结构,支持插入一个点以及询问其余点到某个点的最小曼哈顿距离。
思路:
这是个\(kdtree\)模板题。
\(kdtree\)是一种可以高效处理\(k\)维空间信息的结构。一般我们遇到的是\(2\)维空间或者\(3\)维空间。
一般用来解决的问题为:空间最近点对、空间第\(k\)远点对、矩阵查询等问题,这些问题离线可以离线\(cdq\)解决,但是用\(kdtree\)的话可以在线处理这些问题。
一般认为一次操作期望复杂度是\(\sqrt{n}\)的,但最坏情况下复杂度为\(O(n)\)。所以我们其实可以将它看作一种玄学且比较优美的暴力~一般我们都直接定义全局变量然后大力减枝。
开局建颗树,减枝刷题数!
回到这个题,查询的话\(ans\)注意是全局变量。另外还定义了一个估价函数,含义是到达那个矩形内部的最好情况,显然这个最好情况如果都大于目前的\(ans\),我们可以不用搜索该子树。
如果类似于一个圆就可能被卡到\(O(n^2)\)
细节见代码:
/*
* Author: heyuhhh
* Created Time: 2019/11/22 14:12:30
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e6 + 5;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n, m;
int D;
const int dim = 2;
struct Point {
int d[2], mn[2], mx[2], l, r;
int& operator [] (int x) {return d[x];}
Point(int x = 0, int y = 0) {
l = r = 0;
d[0] = x; d[1] = y;
}
}p[N >> 1];
bool operator < (Point A, Point B) {
return A[D] < B[D];
}
struct kdtree {
int rt, ans; //注意ans定义为全局变量
Point tree[N], T;
void upd(int o) {
Point ls = tree[tree[o].l], rs = tree[tree[o].r];
for(int i = 0; i < dim; i++) {
if(tree[o].l) {
tree[o].mn[i] = min(tree[o].mn[i], ls.mn[i]);
tree[o].mx[i] = max(tree[o].mx[i], ls.mx[i]);
}
if(tree[o].r) {
tree[o].mn[i] = min(tree[o].mn[i], rs.mn[i]);
tree[o].mx[i] = max(tree[o].mx[i], rs.mx[i]);
}
}
}
int build(int l, int r, int now) {
D = now;
int mid = (l + r) >> 1;
nth_element(p + l, p + mid, p + r + 1);
tree[mid] = p[mid];
for(int i = 0; i < dim; i++) {
tree[mid].mn[i] = tree[mid].mx[i] = tree[mid][i];
}
if(l < mid) tree[mid].l = build(l, mid - 1, now ^ 1);
if(r > mid) tree[mid].r = build(mid + 1, r, now ^ 1);
upd(mid);
return mid;
}
void insert(int o, int now) {
D = now;
if(T[D] < tree[o][D]) {
if(tree[o].l) insert(tree[o].l, now ^ 1);
else {
tree[o].l = ++n;
tree[n] = T;
for(int i = 0; i < dim; i++) {
tree[n].mx[i] = tree[n].mn[i] = T[i];
}
}
} else {
if(tree[o].r) insert(tree[o].r, now ^ 1);
else {
tree[o].r = ++n;
tree[n] = T;
for(int i = 0; i < dim; i++) {
tree[n].mx[i] = tree[n].mn[i] = T[i];
}
}
}
upd(o);
}
int dis(Point A, Point B) {
int res = 0;
for(int i = 0; i < dim; i++) {
res += abs(A[i] - B[i]);
}
return res;
}
int get(Point A, Point B) {//估价函数
int res = 0;
for(int i = 0; i < dim; i++) {
res += max(0, A[i] - B.mx[i]) + max(0, B.mn[i] - A[i]);
}
return res;
}
void query(int o) {
ans = min(ans, dis(tree[o], T));
int l = INF, r = INF;
if(tree[o].l) l = get(T, tree[tree[o].l]);
if(tree[o].r) r = get(T, tree[tree[o].r]);
if(l < r) {
if(l < ans) query(tree[o].l);
if(r < ans) query(tree[o].r);
} else {
if(r < ans) query(tree[o].r);
if(l < ans) query(tree[o].l);
}
}
}kd;
void run(){
n = read(), m = read();
for(int i = 1; i <= n; i++) {
int x = read(), y = read();
p[i] = Point(x, y);
}
kd.rt = kd.build(1, n, 0);
while(m--) {
int t = read(), x = read(), y = read();
kd.T = Point(x, y);
if(t == 1) {
kd.insert(kd.rt, 0);
} else {
kd.ans = INF;
kd.query(kd.rt);
printf("%d\n", kd.ans);
}
}
}
int main() {
run();
return 0;
}
【bzoj2648】SJY摆棋子(kdtree)的更多相关文章
- [BZOJ2648] SJY摆棋子 kd-tree
2648: SJY摆棋子 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 5421 Solved: 1910[Submit][Status][Disc ...
- BZOJ2648: SJY摆棋子&&2716: [Violet 3]天使玩偶
BZOJ2648: SJY摆棋子 BZOJ2716: [Violet 3]天使玩偶 BZOJ氪金无极限... 其实这两道是同一题. 附上2648的题面: Description 这天,SJY显得无聊. ...
- 【BZOJ2648】SJY摆棋子 KDtree
[BZOJ2648]SJY摆棋子 Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找 ...
- 【BZOJ2648】SJY摆棋子 [KD-tree]
SJY摆棋子 Time Limit: 20 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 这天,SJY显得无聊.在家自己 ...
- BZOJ 2648: SJY摆棋子 kdtree
2648: SJY摆棋子 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=2648 Description 这天,SJY显得无聊.在家自己玩 ...
- luoguP4169 [Violet]天使玩偶/SJY摆棋子 K-Dtree
P4169 [Violet]天使玩偶/SJY摆棋子 链接 luogu 思路 luogu以前用CDQ一直过不去. bzoj还是卡时过去的. 今天终于用k-dtree给过了. 代码 #include &l ...
- BZOJ2648 SJY摆棋子(KD-Tree)
板子题. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...
- KDTree(Bzoj2648: SJY摆棋子)
题面 传送门 KDTree 大概就是一个分割\(k\)维空间的数据结构,二叉树 建立:每层选取一维为关键字,把中间的点拿出来,递归左右,有个\(STL\)函数nth_element可以用一下 维护:维 ...
- [bzoj2648]SJY摆棋子(带插入kd-tree)
解题关键:带插入kdtree模板题. #include<iostream> #include<cstdio> #include<cstring> #include& ...
- 【kd-tree】bzoj2648 SJY摆棋子
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define ...
随机推荐
- Docker系列01-容器初探
关于容器的发展史 关于容器有不得不说的历史故事,以下资料来自于互联网收集整理所得: 容器概念始于 1979 年提出的 UNIX chroot,它是一个 UNIX 操作系统的系统调用,将一个进程及其子进 ...
- MySQL学习——管理用户权限
MySQL学习——管理用户权限 摘要:本文主要学习了使用DCL语句管理用户权限的方法. 了解用户权限 什么是用户 用户,指的就是操作和使用MySQL数据库的人.使用MySQL数据库需要用户先通过用户名 ...
- Linux系统学习 四、网络基础—互联网概述,互联网接入方式
互联网概述 WWW:万维网 FTP:文件传输协议 E-MAIL:电子邮件 WWW 典型的C/S架构 URL:统一资源定位 协议+域名或IP:端口+网页路径+网页名 http://www.xxx.com ...
- 一个驱动导致的内存泄漏问题的分析过程(meminfo->pmap->slabtop->alloc_calls)
关键词:sqllite.meminfo.slabinfo.alloc_calls.nand.SUnreclaim等等. 下面记录一个由于驱动导致的内存泄漏问题分析过程. 首先介绍问题背景,在一款嵌入式 ...
- jt格式文件与3D数据压缩
介绍 JT是西门子公司推出的PLM通用三维格式,设计为一个开放.高效率的.紧凑,持久性存储的产品数据格式,用于产品可视化.协作和CAD数据共享.JT文件格式包括多方面的数据,以及对曲面边的精准表示,产 ...
- JVM-1-HotSpot server client
64位JDK 默认只能工作在Server模式下 是无法切换到Client模式的 Hot Spot虚拟机Server
- Javascript是如何工作的?
作为一个前端开发者或者全栈开发者,一定非常熟练Javascript.程序员社区Stack Overflow的调查结果显示,Javascript是最常用的编程语言,连续多年排在第一名.发明Javascr ...
- MySQL select from where multiple conditions
Maybe one of the most used MySQL commands is SELECT, that is the way to stract the information from ...
- 【转】Java中的关键字 transient
阅读目录 先解释下Java中的对象序列化 关于transient关键字 举个例子 参考资料 先解释下Java中的对象序列化 在讨论transient之前,有必要先搞清楚Java中序列化的含义: Jav ...
- Codeforces Round #598 (Div. 3) B. Minimize the Permutation 贪心
B. Minimize the Permutation You are given a permutation of length n. Recall that the permutation is ...