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. Question | 关于Android安全的一二事

    本文来自网易云社区 "Question"为网易云易盾的问答栏目,将会解答和呈现安全领域大家常见的问题和困惑.如果你有什么疑惑,也欢迎通过邮件(zhangyong02@corp.ne ...

  3. Oracle physical dataguard with broker部署

    一.环境说明 主库:10.110.96.88 备库:10.110.96.87 数据库实例:gisc 二.主库操作 1.开启force logging ALTER DATABASE FORCE LOGG ...

  4. join ,left join ,right join有什么区别

    join等价于inner join内连接,是返回两个表中都有的符合条件的行. left join左连接,是返回左表中所有的行及右表中符合条件的行.(左表为主表) right join右连接,是返回右表 ...

  5. windows基础知识(win7)

    右击 显示: 对设备进行管理: 在计算机属性中,开远程连接 控制面板: 控制面板下的操作中心: 控制面板下的管理工具: 控制面板下的默认程序: 控制面板下的日期时间: 控制面板下的鼠标: 控制面板下的 ...

  6. flask - 1

    from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, Worl ...

  7. k8s第一个实例创建redis集群服务

    1.创建redis-master-controller.yaml apiVersion: v1 kind: ReplicationController metadata: name: redis-ma ...

  8. C++STL——堆栈

    一.相关定义 原理:stack队列是一个线性存储表,插入和删除只在栈顶进行,从而构成了一个后进先出LIFO表. 入栈&出栈:元素的插入称为入栈,元素的删除称为出栈. stack是一种关联容器, ...

  9. MySQL初始4--去重

    更新表中的字段: update 表名 set 字段=新值,… where 条件: UPDATE语法可以用新值更新原有表行中的各列.SET子句指示要修改哪些列和要给予哪些值.WHERE子句指定应更新哪些 ...

  10. 用vs调试项目页面无样式

    ASP.NET Development Server 上的文件授权 在文件系统网站中,静态文件(例如图像和样式表)遵守 ASP.NET 授权.例如,如果禁用了对静态文件的匿名访问,匿名用户则不能使用文 ...