Description
 
这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N<=500000个初始棋子。和M<=500000个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。
 
Input
 
第一行两个数 N M
以后M行,每行3个数 t x y
如果t=1 那么放下一个黑色棋子
如果t=2 那么放下一个白色棋子
Output
 
对于每个T=2 输出一个最小距离
 
Sample Input
 
2 3
 
1 1
 
2 3
 
2 1 2
 
1 3 3
 
2 4 2
 
Sample Output
1
 
2
HINT
 
 
kdtree可以过
【分析】
大家都知道kd_tree是什么吧,恩
就这样了..好吧,kd_tree一种空间树..看代码就知道了
 /*
唐代李白
《江夏别宋之悌》
楚水清若空,遥将碧海通。人分千里外,兴在一杯中。
谷鸟吟晴日,江猿啸晚风。平生不下泪,于此泣无穷.
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map>
#include <ctime>
#include <cstdlib>
#include <stack>
#include <set>
#define LOCAL
const int INF = 0x7fffffff;
const int MAXN = + ;
const int maxnode = * + * ;
const int MAXM = + ;
const int MAX = ;
using namespace std;
struct Node{//kd_tree
int d[], l, r;
int Max[], Min[];
}t[ + ],tmp; int n,m,root,cmp_d;
int k1, k2, k3, Ans; bool cmp(Node a, Node b){return (a.d[cmp_d]<b.d[cmp_d]) || ((a.d[cmp_d] == b.d[cmp_d]) && (a.d[!cmp_d] < b.d[!cmp_d]));}
void update(int p){
if (t[p].l){
//左边最大的横坐标值
t[p].Max[] = max(t[p].Max[], t[t[p].l].Max[]);
t[p].Min[] = min(t[p].Min[], t[t[p].l].Min[]);
t[p].Max[] = max(t[p].Max[], t[t[p].l].Max[]);
t[p].Min[] = min(t[p].Min[], t[t[p].l].Min[]);
}
if (t[p].r){
t[p].Max[] = max(t[p].Max[], t[t[p].r].Max[]);
t[p].Min[] = min(t[p].Min[], t[t[p].r].Min[]);
t[p].Max[] = max(t[p].Max[], t[t[p].r].Max[]);
t[p].Min[] = min(t[p].Min[], t[t[p].r].Min[]);
}
return;
}
//d是横竖切..
int build(int l, int r, int D){
int mid = (l + r) / ;
cmp_d = D;
//按照cmp的比较顺序在l到r中找到第mid大的元素
nth_element(t + l + , t + mid + , t + r + , cmp);
t[mid].Max[] = t[mid].Min[] = t[mid].d[];
t[mid].Max[] = t[mid].Min[] = t[mid].d[];
//递归建树
if (l != mid) t[mid].l = build(l, mid - , D ^ );
if (r != mid) t[mid].r = build(mid + , r, D ^ );
update(mid);
return mid;
}
void insert(int now){
int D = , p = root;//D还是表示方向
while (){
//边下传边更新
t[p].Max[] = max(t[p].Max[], t[now].Max[]);
t[p].Min[] = min(t[p].Min[], t[now].Min[]);
t[p].Max[] = max(t[p].Max[], t[now].Max[]);
t[p].Min[] = min(t[p].Min[], t[now].Min[]);
//有没有点线段树的感觉..
if (t[now].d[D] >= t[p].d[D]){
if (t[p].r == ){
t[p].r = now;
return;
}else p = t[p].r;
}else{
if (t[p].l == ){
t[p].l = now;
return;
}else p = t[p].l;
}
D = D ^ ;
}
return;
}
int ABS(int x) {return x < ? -x : x;}
//dist越小代表越趋近?
int dist(int p1, int px, int py){
int dist = ;
if (px < t[p1].Min[]) dist += t[p1].Min[] - px;
if (px > t[p1].Max[]) dist += px - t[p1].Max[];
if (py < t[p1].Min[]) dist += t[p1].Min[] - py;
if (py > t[p1].Max[]) dist += py - t[p1].Max[];
return dist;
}
void ask(int p){
int dl, dr, d0;
//哈密顿距离
d0=ABS(t[p].d[] - k2) + ABS(t[p].d[] - k3);
if(d0 < Ans) Ans = d0;
if(t[p].l) dl = dist(t[p].l, k2, k3); else dl = 0x7f7f7f7f;
if(t[p].r) dr = dist(t[p].r, k2, k3); else dr = 0x7f7f7f7f;
//应该是一个启发式的过程。
if(dl < dr){
if(dl < Ans) ask(t[p].l);
if(dr < Ans) ask(t[p].r);
}else{
if(dr < Ans) ask(t[p].r);
if(dl < Ans) ask(t[p].l);
}
} void init(){
//假设0为横坐标
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++)
scanf("%d%d", &t[i].d[], &t[i].d[]);
root = build(, n, );
}
void work(){
for (int i = ; i <= m ;i++){
scanf("%d%d%d", &k1, &k2, &k3);
if (k1 == ){//黑棋
++n;
t[n].Max[] = t[n].Min[] = t[n].d[] = k2;
t[n].Max[] = t[n].Min[] = t[n].d[] = k3;
insert(n);
}else{
Ans = 0x7f7f7f7f;
ask(root);
printf("%d\n", Ans);
}
}
} int main(){ init();
work();
return ;
}
 

【BZOJ2648】【kd_tree】SJY摆棋子的更多相关文章

  1. 【BZOJ2648】SJY摆棋子(KD-Tree)

    [BZOJ2648]SJY摆棋子(KD-Tree) 题面 BZOJ Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一 ...

  2. 【BZOJ2648】SJY摆棋子 KDtree

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

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

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

  4. [bzoj2648/2716]SJY摆棋子_KD-Tree

    SJY摆旗子 bzoj-2648 题目大意:平面上有n个黑子.有m个操作,可以下一颗白子,查询与曼哈顿距离下最近黑子之间的曼哈顿距离,或者下一颗黑子. 注释:$1\le n,m\le 5\cdot 1 ...

  5. BZOJ2648/2716:SJY摆棋子/[Violet]天使玩偶(K-D Tree)

    Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子. ...

  6. 【bzoj2648】 SJY摆棋子

    http://www.lydsy.com/JudgeOnline/problem.php?id=2648 (题目链接) 题意 动态维护二维平面上的点的插入以及最邻近域搜索. Solution KDtr ...

  7. [bzoj2648/2716]SJY摆棋子

    平面上有n个点,要求支持插入一个点和查询一个点的最近点距离 n,m<=500000 用kdtree实现,但是复杂度貌似没法保证.....(莫名加了替罪羊重建更慢了...) #include< ...

  8. BZOJ2648:SJY摆棋子

    浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html 题目传送门:https://lydsy.com/JudgeOnline ...

  9. 【BZOJ2648】SJY摆棋子

    题目大意:维护一个二维平面,平面上初始有 N 个点,支持两种操作:平面加点.查询距离某个指定点的最小哈密顿距离. 题解:学习到了 kd-tree 数据结构. kd-tree 类似于平衡树,即:每个节点 ...

  10. 【bzoj2648】SJY摆棋子(kdtree)

    传送门 题意: 二维平面上有若干个点. 现在要维护一种数据结构,支持插入一个点以及询问其余点到某个点的最小曼哈顿距离. 思路: 这是个\(kdtree\)模板题. \(kdtree\)是一种可以高效处 ...

随机推荐

  1. 【转】蓝牙物理链路类型:SCO和ACL链路

    原文网址:http://blog.chinaunix.net/uid-23193900-id-3272233.html  蓝牙物理链路ACL(Asynchronous Connectionless), ...

  2. 字符串(AC自动机):COCI 2015 round 5 divljak

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAy0AAANaCAIAAAALVTQoAAAgAElEQVR4nOy9X2hbx773PXfrQgQjDq

  3. vaddin使用技巧

    添加外部jar包的方法: 在项目目录下建立lib文件夹,把外部jar包复制到该文件夹底下.右键该jar包-构建路径-添加至构建路径即可.也可以配置构建路径-库-添加jar.

  4. 几款常用Eclipse java插件

    以下是我最近常用的几款Eclipse java插件: ADT Plugin https://dl-ssl.google.com/android/eclipse/ WindowBuilder Pro  ...

  5. JavaScript高级程序设计6.pdf

    ECMAScript通过RegExp类型来支持正则表达式 var expression=/pattern/flags;其中模式(pattern)部分是正则表达式,可以包含字符类.限定符.分组.向前查找 ...

  6. Hdu 5036-Explosion 传递闭包,bitset,期望/概率

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5036 Explosion Time Limit: 6000/3000 MS (Java/Others)   ...

  7. JavaScript DOM-Ready 机制

    IE9开始和其他现代浏览器可以通过绑定DOMContentLoaded事件:IE9之前的的浏览器需要绑定onreadystatechange事件并等待readyState为"complete ...

  8. 用python 装饰器打log

    # coding=utf-8    from time import time def logged(when):     def log(f,*args,**kargs):         prin ...

  9. 【Android - 框架】之GreenDao的使用

    上一篇博客([Android - 框架]之ORMLite的使用)中介绍了ORMLite的基本使用,今天我们来研究以下GreenDao的使用. GreenDao和ORMLite一样,都是基于ORM(Ob ...

  10. app启动其他应用

    因开发需要内包一个app,所以要启动一个app,这种操作 如果知道包名和类名 其实很简单 只需要将包名内嵌即可(一般情况 我们都可以解压或者反接拿到) 代码如下: Intent intent = ne ...