题目链接

初始的时候有一些棋子, 然后给两种操作, 一种是往上面放棋子。 另一种是给出一个棋子的位置, 问你离它最近的棋子的曼哈顿距离是多少。

写了指针版本的kd树, 感觉这个版本很好理解。

#include <bits/stdc++.h>
using namespace std;
#define mk(x, y) make_pair(x, y)
#define mem(a) memset(a, 0, sizeof(a))
#define fi first
#define se second
typedef pair<int, int> pll;
const int inf = 2e9;
int cmpflag;
pll a[];
struct kdTree
{
pll point;
kdTree *l, *r;
int x[], y[];
kdTree(){};
kdTree(const pll& par): point(par)
{
x[] = x[] = par.fi;
y[] = y[] = par.se;
l = r = NULL;
}
int getMin(const pll& par)
{
int ret = ;
if(par.fi < x[])
ret += x[] - par.fi;
if(par.fi > x[])
ret += par.fi - x[];
if(par.se < y[])
ret += y[] - par.se;
if(par.se > y[])
ret += par.se - y[];
return ret;
}
void pushUp(const kdTree* par)
{
x[] = min(x[], par->x[]);
x[] = max(x[], par->x[]);
y[] = min(y[], par->y[]);
y[] = max(y[], par->y[]);
}
};
bool cmp(const pll& lhs, const pll& rhs)
{
if(cmpflag)
return lhs.se < rhs.se;
return lhs.fi < rhs.fi;
}
int getDistance(const pll& lhs, const pll& rhs)
{
return abs(lhs.fi-rhs.fi)+abs(lhs.se-rhs.se);
}
void build(kdTree*& p, int l, int r, int w)
{
if(l > r)
return ;
int mid = l + r >> ;
cmpflag = w;
nth_element(a+l, a+mid, a+r+, cmp);
p = new kdTree(a[mid]);
build(p->l, l, mid-, w^);
build(p->r, mid+, r, w^);
if(p->l)
p->pushUp(p->l);
if(p->r)
p->pushUp(p->r);
}
void add(kdTree*& p, const pll& q, int w)
{
if(!p) {
p = new kdTree(q);
return ;
}
cmpflag = w;
if(cmp(q, p->point)) {
add(p->l, q, w^);
p->pushUp(p->l);
} else {
add(p->r, q, w^);
p->pushUp(p->r);
}
}
void query(kdTree* p, const pll& q, int& ans)
{
ans = min(ans, getDistance(q, p->point));
int lDis = p->l?p->l->getMin(q):inf;
int rDis = p->r?p->r->getMin(q):inf;
if(lDis < rDis) {
if(lDis < ans)
query(p->l, q, ans);
if(ans > rDis)
query(p->r, q, ans);
} else {
if(rDis < ans) {
query(p->r, q, ans);
}
if(ans > lDis)
query(p->l, q, ans);
}
}
int main()
{
int n, m, x, y, sign;
cin>>n>>m;
for(int i = ; i <= n; i++) {
scanf("%d%d", &a[i].fi, &a[i].se);
}
kdTree *root = new kdTree();
build(root, , n, );
while(m--) {
scanf("%d%d%d", &sign, &x, &y);
if(sign == ) {
add(root, mk(x, y), );
} else {
int ans = inf;
query(root, mk(x, y), ans);
printf("%d\n", ans);
}
}
return ;
}

bzoj 2648 SJY摆棋子 kd树的更多相关文章

  1. bzoj 2648 SJY摆棋子 —— K-D树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648 学习资料:https://blog.csdn.net/zhl30041839/arti ...

  2. BZOJ 2648: SJY摆棋子(K-D Tree)

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 6051  Solved: 2113[Submit][Status][Discuss] Descript ...

  3. BZOJ 2648: SJY摆棋子

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

  4. BZOJ 2648: SJY摆棋子 kdtree

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

  5. bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree

    2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 Time Limit: 20 Sec  Memory Limit: 128 MB Description 这天,S ...

  6. BZOJ 2648 SJY摆棋子(KD树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2716 [题目大意] 给出一些点,同时不断插入点和询问某点离插入点最近距离 [题解] 我 ...

  7. BZOJ 2648 SJY摆棋子(KD Tree)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2648 题意: 思路: KDtree模板题. 参考自http://www.cnblogs.com/ra ...

  8. bzoj 2648 SJY摆棋子——KDtree

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648 第一道KDtree! 学习资料:https://blog.csdn.net/zhl30 ...

  9. bzoj 2648: SJY摆棋子【KD-tree】

    其实理论上cdq更优 核心是依次取x值.y值的mid作为当前节点,向两边递归建立二叉树,树上维护size:子树大小:mx[0/1]:子树内最大x/y:mn[0/1]:子树内最小x/y:d[0/1]:这 ...

随机推荐

  1. js前台获取list的demo

    后台 bannerlist=homePageService.searchBanner(bannerVO); // 注意这里的Gson的构建方式为GsonBuilder,区别于test1中的Gson g ...

  2. 使用SQL脚本访问操作远程数据库

    USE [Hik] GO /****** Object: StoredProcedure [dbo].[sp_test] Script Date: 08/21/2015 09:55:21 ****** ...

  3. jquery find()和filter()的区别

    在写js查找当前标签下某一子元素的子元素集合时,用到了此方法 $(".flyout-trigger").mouseover(function(){ var maxnum=$(thi ...

  4. thinkphp使用模块/控制器/操作访问时出现No input file specified.解决方式

    thinkphp使用 http://serverName/index.php/模块/控制器/操作 访问时,出现了 No input file specified. 的错误 解决办法: 一: 开启cgi ...

  5. nginx之如何获取真实客户端ip

    nginx的配置文件中日志格式加入$http_x_forwarded_for--> log_format access '$remote_addr - $remote_user [$time_l ...

  6. DIRECTORY_SEPARATOR的作用

    IRECTORY_SEPARATOR是php的内部常量,用于显示系统分隔符的命令,不需要任何定义与包含即可直接使用. 在windows下路径分隔符是/(当然/在部分系统上也是可以正常运行的),在lin ...

  7. Robberies(HDU 2955 DP01背包)

    Robberies Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  8. Asp.net MVC Web.config配置技巧

    一.视图引入命名空间的设置 之前经常写这样的代码,而且每个页面都要写: @model IEnumerable<MvcStart.Models.People_Model> 其实有一种很方便的 ...

  9. LINQ to SQL和Entity Framework对比与关联 (转载)

    LINQ to SQL和Entity Framework对比与关联       LINQ to SQL和Entity Framework都是一种包含LINQ功能的对象关系映射技术.他们之间的本质区别在 ...

  10. python 递归展开嵌套的序列(生成器用法)

    任何使用yield语句的函数都称为生成器.调用生成器函数将创建一个对象,该对象通过连续调用next()方法(在python3中是__next__())生成结果序列. next()调用使生成器函数一直运 ...