[BZOJ2648] SJY摆棋子 kd-tree
2024-08-29 20:29:55
2648: SJY摆棋子
Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 5421 Solved: 1910
[Submit][Status][Discuss]
Description
这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N<=500000个初始棋子。和M<=500000个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。
Input
第一行两个数 N M
以后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
1 1
2 3
2 1 2
1 3 3
2 4 2
Sample Output
1
2
2
HINT
kdtree可以过
Source
kd-tree裸题
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<cstdio>
#include<algorithm>
#define maxn 1000001
using namespace std;
struct data {
int mn[],mx[],l,r,d[];
data() {mn[]=mn[]=mx[]=mx[]=l=r=d[]=d[]=;}
}t[maxn*];
int n,m;
int nowd;
bool cmp(data t1,data t2) {return t1.d[nowd]==t2.d[nowd]?t1.d[!nowd]<t2.d[!nowd]:t1.d[nowd]<t2.d[nowd];}
void update(int x) {
if(t[x].l) {
t[x].mx[]=max(t[x].mx[],t[t[x].l].mx[]);
t[x].mn[]=min(t[x].mn[],t[t[x].l].mn[]);
t[x].mx[]=max(t[x].mx[],t[t[x].l].mx[]);
t[x].mn[]=min(t[x].mn[],t[t[x].l].mn[]);
}
if(t[x].r) {
t[x].mx[]=max(t[x].mx[],t[t[x].r].mx[]);
t[x].mn[]=min(t[x].mn[],t[t[x].r].mn[]);
t[x].mx[]=max(t[x].mx[],t[t[x].r].mx[]);
t[x].mn[]=min(t[x].mn[],t[t[x].r].mn[]);
}
}
int build(int l,int r,int D) {
int mid=l+r>>;
nowd=D;
nth_element(t+l+,t+mid+,t+r+,cmp);
if(l!=mid) t[mid].l=build(l,mid-,!D);
if(r!=mid) t[mid].r=build(mid+,r,!D);
t[mid].mx[]=t[mid].mn[]=t[mid].d[];
t[mid].mx[]=t[mid].mn[]=t[mid].d[];
update(mid);
return mid;
}
void insert(int &now,int D,data x) {
if(!now) {now=++n;t[now]=x;t[now].mn[]=t[now].mx[]=x.d[];t[now].mx[]=t[now].mn[]=x.d[];return;}
if(x.d[D]>t[now].d[D]) insert(t[now].r,!D,x);
else insert(t[now].l,!D,x);
update(now);
}
int dis(int now,data x) {
int re=;
if(x.d[]<t[now].mn[]) re+=t[now].mn[]-x.d[];
if(x.d[]>t[now].mx[]) re+=x.d[]-t[now].mx[];
if(x.d[]<t[now].mn[]) re+=t[now].mn[]-x.d[];
if(x.d[]>t[now].mx[]) re+=x.d[]-t[now].mx[];
return re;
}
int ans;
void query(int now,data x) {
ans=min(ans,abs(t[now].d[]-x.d[])+abs(t[now].d[]-x.d[]));
int dl,dr;
if(t[now].l) dl=dis(t[now].l,x); else dl=;
if(t[now].r) dr=dis(t[now].r,x); else dr=;
if(dl<dr) {
if(dl<ans) query(t[now].l,x);
if(dr<ans) query(t[now].r,x);
}
else {
if(dr<ans) query(t[now].r,x);
if(dl<ans) query(t[now].l,x);
}
}
int main() {
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d%d",&t[i].d[],&t[i].d[]);
int mid=build(,n,);
for(int i=;i<=m;i++) {
int tp;data x;
scanf("%d%d%d",&tp,&x.d[],&x.d[]);
if(tp==) insert(mid,,x);
else {ans=;query(mid,x);printf("%d\n",ans);}
}
}
最新文章
- java+jsp+servlet实现分页
- PDA手持终端扫描条码开单打印一体 结合后台电脑系统 数据同步交互解决方案
- 五、HTML判断输入长度,体会字体颜色变化
- BIEE修改图片步骤:修改BANNER
- C#实现文件下载
- JedisPool使用原理和源代码
- 【HTML5】DOMContentLoaded事件
- 一、MongoDB安装及启动
- Android学习笔记--处理UI事件
- bzoj 3626: [LNOI2014]LCA
- java 常用正则表达式总结
- BZOJ_2580_[Usaco2012 Jan]Video Game_AC自动机+DP
- ubuntu16.04开机时的.local问题
- linux部署的flask项目配置static
- 在Eclipse中运行Web项目Jsp网页时提示端口被占用的解决办法:Several ports (8005, 8888, 8009) required by Tomcat v9.0 Server at localhost are already in use.
- CentOS查看进程、杀死进程、启动进程等常用命令
- spring cloud学习(五) 配置中心
- Netbeans 8.0配置Python开发环境
- SAX,功能强大的 API
- combobox组合框
热门文章
- 关于MySQL的异常处理 Can&#39;t connect to MySQL server on localhost (10061)解决方法
- 使用 TListView 控件(2)
- 更新协同开发工具SVN的链接的服务器地址
- 瀑布模型&;螺旋模型
- JavaScript页面跳转
- [POJ1631]Bridging signals
- VS查看DLL接口
- [poj 3693]后缀数组+出现次数最多的重复子串
- POJ1847:Tram(最短路)
- 如何使主机和虚拟机IP处于同一网段(内网渗透专用)