SJY摆棋子

Time Limit: 20 Sec  Memory Limit: 128 MB
[Submit][Status][Discuss]

Description

  这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N个初始棋子,和M个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。

Input

  第一行两个数 N M
  然后N行,每行2个数 x y,表示初始棋子
  以后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

  N<=500000 , M<=500000

Main idea

  在平面上加入黑点,对于询问一个坐标到其它点的曼哈顿距离中最小的一个。

Solution

  这题显然是一道KD-tree的模板题。

  我们来考虑如何估价,由于求的是最小的曼哈顿距离,我们可以这样估价:

  

  (其实我也并不懂为什么可以这样估,详情可以查询“n+e KDtree在信息学奥赛中的应用”

Code

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<map>
using namespace std; const int ONE=;
const int INF=; int n,m;
int t,x,y;
int cnt,Ans;
int root;
int Ran; struct power
{
int l,r;
int x,y;
int minx,miny;
int maxx,maxy;
}a[ONE]; int get()
{
int res=,Q=;char c;
while( (c=getchar())< || c> )
if(c=='-')Q=-;
res=c-;
while( (c=getchar())>= && c<= )
res=res*+c-;
return res*Q;
} namespace KD
{
void Update(int i)
{
if(a[i].l)
{
a[i].minx=min(a[i].minx,a[a[i].l].minx); a[i].miny=min(a[i].miny,a[a[i].l].miny);
a[i].maxx=max(a[i].maxx,a[a[i].l].maxx); a[i].maxy=max(a[i].maxy,a[a[i].l].maxy);
}
if(a[i].r)
{
a[i].minx=min(a[i].minx,a[a[i].r].minx); a[i].miny=min(a[i].miny,a[a[i].r].miny);
a[i].maxx=max(a[i].maxx,a[a[i].r].maxx); a[i].maxy=max(a[i].maxy,a[a[i].r].maxy);
}
} int cmp(const power &a,const power &b)
{
if(Ran) return a.x<b.x;
return a.y<b.y;
} int Build(int l,int r,int T)
{
int mid=(l+r)/;
Ran=T;
nth_element(a+l, a+mid+, a+r+, cmp);
if(l<mid) a[mid].l = Build(l,mid-,T^);
if(mid<r) a[mid].r = Build(mid+,r,T^);
Update(mid);
return mid;
}
} void Update(int &i,int x,int y,int T)
{
if(!i)
{
i=++cnt;
a[i].x=a[i].minx=a[i].maxx=x;
a[i].y=a[i].miny=a[i].maxy=y;
return;
} if(T)
{
if(x < a[i].x) Update(a[i].l,x,y,T^);
else Update(a[i].r,x,y,T^);
KD::Update(i);
}
else
{
if(y < a[i].y) Update(a[i].l,x,y,T^);
else Update(a[i].r,x,y,T^);
KD::Update(i);
}
} int dist(int x1,int y1,int x2,int y2)
{
return abs(x1-x2)+abs(y1-y2);
} int dist(int i,int x,int y)
{
return max(a[i].minx-x,)+max(x-a[i].maxx,) + max(a[i].miny-y,)+max(y-a[i].maxy,);
} void Query(int i,int x,int y)
{
if(!i) return;
Ans=min(Ans,dist(x,y , a[i].x,a[i].y));
int l=dist(a[i].l,x,y);
int r=dist(a[i].r,x,y);
if(l<r)
{
if(l<=Ans) Query(a[i].l,x,y);
if(r<=Ans) Query(a[i].r,x,y);
}
else
{
if(r<=Ans) Query(a[i].r,x,y);
if(l<=Ans) Query(a[i].l,x,y);
}
} int main()
{
n=get(); m=get();
for(int i=;i<=n;i++)
{
x=get(); y=get();
a[i].x=a[i].minx=a[i].maxx=x;
a[i].y=a[i].miny=a[i].maxy=y;
} cnt=n;
root=KD::Build(,n,); for(int i=;i<=m;i++)
{
t=get(); x=get(); y=get();
if(t==)
{
n++;
a[n].x=a[n].minx=a[n].maxx=x;
a[n].y=a[n].miny=a[n].maxy=y;
Update(root,x,y,);
}
else
{
Ans=INF;
Query(root,x,y);
printf("%d\n",Ans);
}
}
}

【BZOJ2648】SJY摆棋子 [KD-tree]的更多相关文章

  1. luogu4169 [Violet]天使玩偶/SJY摆棋子 / bzoj2648 SJY摆棋子 k-d tree

    k-d tree + 重构的思想,就能卡过luogu和bzoj啦orz #include <algorithm> #include <iostream> #include &l ...

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

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

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

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

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

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

  5. Bzoj2648 SJY摆棋子

    Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 3128  Solved: 1067 Description 这天,SJY显得无聊.在家自己玩.在一个 ...

  6. bzoj 2648 SJY摆棋子 kd树

    题目链接 初始的时候有一些棋子, 然后给两种操作, 一种是往上面放棋子. 另一种是给出一个棋子的位置, 问你离它最近的棋子的曼哈顿距离是多少. 写了指针版本的kd树, 感觉这个版本很好理解. #inc ...

  7. 2019.01.14 bzoj2648: SJY摆棋子(kd-tree)

    传送门 kd−treekd-treekd−tree模板题. 题意简述:支持在平面上插入一个点,求对于一个点的最近点对. 思路:cdqcdqcdq是一种很不错的分治方法 只是好像码量有点窒息 所以我用了 ...

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

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

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

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

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

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

随机推荐

  1. 记一次艰难的CTP调试

    一个atmel,mxt540e的CTP触摸屏. 中断配置为下降沿,输入上拉. 总是只能触发一次中断,中断脚就一直低电平,无法拉高.这只是表面现象   不停找底层I2C驱动,改代码,没用.要靠波形来说话 ...

  2. 给socks-proxy-agent增加认证

    由于需要使用socks代理,查看了nodejs的各种socks库,最终的结论是socks库是其中最完善的,而socks-proxy-agent是以其为基础的封装,可以直接和http模块对接. 不过在尝 ...

  3. 单链表无head各种操作及操作实验

    #encoding=utf-8 class ListNode: def __init__(self,x): self.val=x; self.next=None;   #链表逆序 def revers ...

  4. Kubernetes实战 高可用集群搭建,配置,运维与应用

    1-1 K8S导学 1-2 搭建K8S集群步骤和要点介绍 1-3 搭建三节点Ubuntu环境 1-4 安装容器引擎 1-5 下载Kubeadm.node组件和命令行工具 1-6 向集群中加入worke ...

  5. 【java并发编程实战】第八章:线程池的使用

    1.线程饥饿锁 定义:在线程池中,如果任务的执行依赖其他任务,那么可能会产生线程饥饿锁.尤其是单线程线程池. 示例: public class ThreadDeadStarveTest { publi ...

  6. 在Code::Blocks中编译和使用wxWidgets3.0.0教程

      跳转至:指南,搜索 注意,编译Code :: Blocks的对wxWidgets的3.0.0链接不是很稳定,但该库至少可以被正确编译,(只是使用的时候可能会有问题):CodeBlocks开发商都在 ...

  7. 切换pip源的简便方法

    网上大部分帖子讲的都是打开配置文件修改,那样太麻烦了,其实只要一行命令搞定: pip config set global.index-url https://pypi.tuna.tsinghua.ed ...

  8. 牛客 小a与星际探索

    链接:https://ac.nowcoder.com/acm/contest/317/C来源:牛客网 小a正在玩一款星际探索游戏,小a需要驾驶着飞船从1号星球出发前往n号星球.其中每个星球有一个能量指 ...

  9. argos3-simulator

    如何修改控制器: CVector2: class CVector2 { friend class CRotationMatrix2; friend class CTransformationMatri ...

  10. 了解游戏编程与 AI

    噫语系列... 闲话 最近在重写我的一个 QQ 群机器人项目,并尝试将它改成更通用的结构,以方便在未来加入对 Wechat 和 Telegram 的支持. 在查资料的过程中,发现很多人认为一个群内多人 ...