【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 ...
随机推荐
- ERROR: Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: '/Library/Python/2.7/site-packages/itsdangerous' Consider using the `--user` option or check the permissions
近期练习flask写个blog, 安装flask扩展时 pip install Flask-WTF 报ERROR: Could not install packages due to an Envir ...
- python Djanjo csrf说明与配置
Django csrf CSRF 全称(Cross Site Request Forgery)跨站请求伪造.也被称为One Click Attack和Session Riding,通常缩写为CSR ...
- Scrapy的Spider类和CrawlSpider类
Scrapy shell 用来调试Scrapy 项目代码的 命令行工具,启动的时候预定义了Scrapy的一些对象 设置 shell Scrapy 的shell是基于运行环境中的python 解释器sh ...
- SQL注入神器———Sqlmap!
Sqlmap 开源,python编写 支持5种SQL注入检测技术: 1.基于布尔的注入检测 2.基于时间的注入检测 3.基于错误的注入检测 4.基于UNION联合查询的检测 5.基于堆叠查询的检测 支 ...
- 浅谈JS函数节流及应用场景
说完防抖,下面我们讲讲节流,规矩就不说了,先上代码: <!DOCTYPE html> <html lang="en"> <head> <m ...
- HTML5常见的取值与单位
HTML5常见的取值与单位 长度单位包括 相对长度单位包括:em, ex, ch, rem, vw, vh, vmax, vmin 绝对长度单位包括:cm, mm, q, in, pt, pc ...
- 面向对象程序设计(JAVA) 第13周学习指导及要求
2019面向对象程序设计(Java)第13周学习指导及要求 (2019.11.19-2019.11.25) 学习目标 (1) 掌握事件处理的基本原理,理解其用途: (2) 掌握AWT事件模型的工作 ...
- git 代码管理
- HTML连载48-清除浮动的其中两种方式
一.清除浮动的方式一 给前面一个父元素设置高度,注意:企业开发中能不写高度就不写高度 <!DOCTYPE html> <html lang="en"> & ...
- 避免Java中NullPointerException的Java技巧和最佳实践
Java中的NullPointerException是我们最经常遇到的异常了,那我们到底应该如何在编写代码是防患于未然呢.下面我们就从几个方面来入手,解决这个棘手的问题吧. 值得庆幸的是,通过应用 ...