传送门

题意:

二维平面上有若干个点。

现在要维护一种数据结构,支持插入一个点以及询问其余点到某个点的最小曼哈顿距离。

思路:

这是个\(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)的更多相关文章

  1. [BZOJ2648] SJY摆棋子 kd-tree

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 5421  Solved: 1910[Submit][Status][Disc ...

  2. BZOJ2648: SJY摆棋子&&2716: [Violet 3]天使玩偶

    BZOJ2648: SJY摆棋子 BZOJ2716: [Violet 3]天使玩偶 BZOJ氪金无极限... 其实这两道是同一题. 附上2648的题面: Description 这天,SJY显得无聊. ...

  3. 【BZOJ2648】SJY摆棋子 KDtree

    [BZOJ2648]SJY摆棋子 Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找 ...

  4. 【BZOJ2648】SJY摆棋子 [KD-tree]

    SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 这天,SJY显得无聊.在家自己 ...

  5. BZOJ 2648: SJY摆棋子 kdtree

    2648: SJY摆棋子 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=2648 Description 这天,SJY显得无聊.在家自己玩 ...

  6. luoguP4169 [Violet]天使玩偶/SJY摆棋子 K-Dtree

    P4169 [Violet]天使玩偶/SJY摆棋子 链接 luogu 思路 luogu以前用CDQ一直过不去. bzoj还是卡时过去的. 今天终于用k-dtree给过了. 代码 #include &l ...

  7. BZOJ2648 SJY摆棋子(KD-Tree)

    板子题. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  8. KDTree(Bzoj2648: SJY摆棋子)

    题面 传送门 KDTree 大概就是一个分割\(k\)维空间的数据结构,二叉树 建立:每层选取一维为关键字,把中间的点拿出来,递归左右,有个\(STL\)函数nth_element可以用一下 维护:维 ...

  9. [bzoj2648]SJY摆棋子(带插入kd-tree)

    解题关键:带插入kdtree模板题. #include<iostream> #include<cstdio> #include<cstring> #include& ...

  10. 【kd-tree】bzoj2648 SJY摆棋子

    #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define ...

随机推荐

  1. 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 ...

  2. python Djanjo csrf说明与配置

     Django csrf  CSRF 全称(Cross Site Request Forgery)跨站请求伪造.也被称为One Click Attack和Session Riding,通常缩写为CSR ...

  3. Scrapy的Spider类和CrawlSpider类

    Scrapy shell 用来调试Scrapy 项目代码的 命令行工具,启动的时候预定义了Scrapy的一些对象 设置 shell Scrapy 的shell是基于运行环境中的python 解释器sh ...

  4. SQL注入神器———Sqlmap!

    Sqlmap 开源,python编写 支持5种SQL注入检测技术: 1.基于布尔的注入检测 2.基于时间的注入检测 3.基于错误的注入检测 4.基于UNION联合查询的检测 5.基于堆叠查询的检测 支 ...

  5. 浅谈JS函数节流及应用场景

    说完防抖,下面我们讲讲节流,规矩就不说了,先上代码: <!DOCTYPE html> <html lang="en"> <head> <m ...

  6. HTML5常见的取值与单位

    HTML5常见的取值与单位     长度单位包括 相对长度单位包括:em, ex, ch, rem, vw, vh, vmax, vmin 绝对长度单位包括:cm, mm, q, in, pt, pc ...

  7. 面向对象程序设计(JAVA) 第13周学习指导及要求

    2019面向对象程序设计(Java)第13周学习指导及要求 (2019.11.19-2019.11.25)   学习目标 (1) 掌握事件处理的基本原理,理解其用途: (2) 掌握AWT事件模型的工作 ...

  8. git 代码管理

  9. HTML连载48-清除浮动的其中两种方式

    一.清除浮动的方式一 给前面一个父元素设置高度,​注意:企业开发中能不写高度就不写高度 <!DOCTYPE html> <html lang="en"> & ...

  10. 避免Java中NullPointerException的Java技巧和最佳实践

    Java中的NullPointerException是我们最经常遇到的异常了,那我们到底应该如何在编写代码是防患于未然呢.下面我们就从几个方面来入手,解决这个棘手的​问题吧.​ 值得庆幸的是,通过应用 ...