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. guacamole实现剪切复制

    主要功能是实现把堡垒机的内容复制到浏览器端,把浏览器端的文本复制到堡垒机上. 借助一个中间的文本框,现将堡垒机内容复制到一个文本框,然后把文本框内容复制出来.或者将需要传递到堡垒机的内容先复制到文本框 ...

  2. 纯js生成QRCode

    纯js,不依赖jquery,非常好用,废话不多说,直接上代码! <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  3. Scala学习笔记(二):运行脚本文件

    在某个目录(如:F:\)下新建一个文本文件,命名为:hello.scala 其内容为: println("Hello World!") 那么这个时候该怎么运行这个脚本文件呢? 通过 ...

  4. React切换显示和隐藏

    1 {radioChange >= 0 && 2 <div> 3 {radioChange === 0 ? ( 4 <div className={style. ...

  5. 在Kotlin上怎样用Mockito2 mock final 类(KAD 23)

    作者:Antonio Leiva 时间:Mar 2, 2017 原文链接:https://antonioleiva.com/mockito-2-kotlin/ 如我们在前面文章中谈到的,Kotlin最 ...

  6. 14.0 native webview H5切换

    在讲这章之前先说明一个问题,那就是 native webview 都是属于原生的...webview目前用的比较多的是谷歌内核和腾讯X5内核  H5是网页! 还是安卓市场---直接写好脚本进入个人中心 ...

  7. 孤荷凌寒自学python第六十八天学习并实践beautifulsoup模块1

    孤荷凌寒自学python第六十八天学习并实践beautifulsoup模块1 (完整学习过程屏幕记录视频地址在文末) 感觉用requests获取到网页的html源代码后,更重要的工作其实是分析得到的内 ...

  8. int,long,long long类型的范围

    [内置类型] int      -2147483648-2147483647  //现在编译器的int型是32位的,以前为16位的范围是-32768~32767 unsigned  int   0-4 ...

  9. [org.hibernate.engine.jdbc.spi.SqlExceptionHelper]SQL Error: 1064, SQLState: 42000问题的解决办法

    [org.hibernate.engine.jdbc.spi.SqlExceptionHelper]SQL Error: 1064, SQLState: 42000问题的解决办法. 出现这种情况的原因 ...

  10. css如何选择相同class下的第一个class元素和最后一个元素?

    如图,如果像选择类名为  class="exerciseInfo"  中的第一个和最后一个div,做法如下: 选择第一个类名: .exerciseInfo: nth-of-type ...