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. python os模块atime ,ctime,mtime意义

    ython的os.stat中主要的时间信息有三个:st_mtime,st_atime,st_ctime.   1.st_mtime:time of last modification      最后一 ...

  2. CentOS修改网卡名称

    转 一.问题说明 测试环境中出现的小问题,因为虚拟机之间经常复制来复制去,导致网卡配置这块的不一致现象. 配置文件的信息: [root@ora10g network-scripts]# catifcf ...

  3. Percona-Tookit工具包之pt-mysql-summary

      Preface       Sometimes we need to collect information of  MySQL server as a report when we first ...

  4. ES5新增数组方法(2):map

    通过指定函数处理数组的每个元素,并返回处理后的数组. 1.计算数组中每个元素的平方 let arr = [1, 2, 3, 4, 5, 6]; let newArr = arr.map(item =& ...

  5. Qt Qpushbutton美化问题

    昨天在论坛看到一个网友的提问,如下 我想到的第一个就是可能需要重载Pushbutton,不过看到有网友回复可以使用stykesheet解决,今天尝试了一下,还是没有成功, 一下是我使用车重载的Push ...

  6. bugku 字符正则

    字符?正则? <?php highlight_file('2.php'); $key='KEY{********************************}'; $IM= preg_mat ...

  7. MySQL☞length函数

    length(字符串/列名):求出该字符串/列名中字符的个数 格式: select  length(列名)  from 表名 如下图:

  8. 深入Python的类和对象

    多态:不同的子类对象,可以调用相同的父类方法,通过改写父类的方法,产生不同的执行结果 instance和type的区别: instance能够顺延到父类,比对对象与父类是否类型一致.而type只能比对 ...

  9. 06-Mysql数据库----表的操作

    06-表的操作   本节掌握 存储引擎介绍(了解) 表的增删改查 一.存储引擎(了解) 前几节我们知道mysql中建立的库===>文件夹,库中的表====>文件 现实生活中我们用来存储数据 ...

  10. ubuntu中 VI 方向键、删除键问题

    这两天重新装的ubuntu系统,发觉使用VI时,方向键按下去后变成ABCD,删除键无效.网上搜寻一番,应该是VI软件本身的问题,顾卸载重装即可,步骤如下: 1.执行命令 sudo apt-get re ...