[bzoj2648][kd-tree]SJY摆棋子
来源:互联网 发布:win7自动开关机软件 编辑:程序博客网 时间:2024/04/29 13:00
Description
这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是
曼哈顿距离 即(|x1-x2|+|y1-y2|)
。现在给出N<=500000个初始棋子。和M<=500000个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。
Input
第一行两个数 N M
以后N行 每行两个数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
kdtree可以过
题解
算法这个Hint都这么明显的摆出来了哈哈哈哈哈你还去搞别的干啥快来一起学
兹磁修改kdtree啊
对黑点建kdtree,然后每次输入黑点就往里面插,白点就在kdtree里面找
自己yy了一个修改的操作,就是递归插空找。对于每个点,记录划分他的平面编号,然后每次让插进去这个点在这个根记录的平面上和他比一比。比他小就去根的左孩子,反之就去右孩子
如果左孩子或者右孩子为0就代表可以在这里插啦。那么记录就好
于是就TLE了
怎么办??
改int啊哈哈哈哈哈哈
#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>using namespace std;int INF=(1<<30);struct node{ int id; int lc,rc,d[2],mx[2],mn[2];}tr[1111000];int len,root,n,m;void update(int x){ int lc=tr[x].lc,rc=tr[x].rc; if(lc)for(int i=0;i<=1;i++)tr[x].mx[i]=max(tr[x].mx[i],tr[lc].mx[i]),tr[x].mn[i]=min(tr[x].mn[i],tr[lc].mn[i]); if(rc)for(int i=0;i<=1;i++)tr[x].mx[i]=max(tr[x].mx[i],tr[rc].mx[i]),tr[x].mn[i]=min(tr[x].mn[i],tr[rc].mn[i]);}int p[2];int cmpd;bool cmp(node n1,node n2){ return n1.d[cmpd]<n2.d[cmpd] || n1.d[cmpd]==n2.d[cmpd] && n1.d[cmpd^1]<n2.d[cmpd^1];}int bt(int l,int r,int d){ int mid=(l+r)/2,now; cmpd=d;now=mid; nth_element(tr+l,tr+mid,tr+r+1,cmp); tr[now].mx[0]=tr[now].mn[0]=tr[now].d[0]; tr[now].mx[1]=tr[now].mn[1]=tr[now].d[1]; if(l<mid)tr[now].lc=bt(l,mid-1,d^1); if(mid<r)tr[now].rc=bt(mid+1,r,d^1); update(now); return now;}int nowx,nowy,minn;void ins(int now){ int p=root; while(1) { if(tr[p].mx[0]<tr[now].mx[0])tr[p].mx[0]=tr[now].mx[0]; if(tr[p].mx[1]<tr[now].mx[1])tr[p].mx[1]=tr[now].mx[1]; if(tr[p].mn[0]>tr[now].mn[0])tr[p].mn[0]=tr[now].mn[0]; if(tr[p].mn[1]>tr[now].mn[1])tr[p].mn[1]=tr[now].mn[1]; if(tr[now].d[cmpd]<tr[p].d[cmpd]) { if(tr[p].lc==0){tr[p].lc=now;return ;} else p=tr[p].lc; } else { if(tr[p].rc==0){tr[p].rc=now;return ;} else p=tr[p].rc; } cmpd^=1; }}int getmin(int now,int x,int y){ int ret=0; if(x>tr[now].mx[0])ret+=x-tr[now].mx[0]; if(x<tr[now].mn[0])ret+=tr[now].mn[0]-x; if(y>tr[now].mx[1])ret+=y-tr[now].mx[1]; if(y<tr[now].mn[1])ret+=tr[now].mn[1]-y; return ret;}void solmin(int now){ int d0=abs(nowx-tr[now].d[0])+abs(nowy-tr[now].d[1]); if(d0<minn)minn=d0; int dl=INF,dr=INF; if(tr[now].lc)dl=getmin(tr[now].lc,nowx,nowy); if(tr[now].rc)dr=getmin(tr[now].rc,nowx,nowy); if(dl<dr) { if(dl<minn)solmin(tr[now].lc); if(dr<minn)solmin(tr[now].rc); } else { if(dr<minn)solmin(tr[now].rc); if(dl<minn)solmin(tr[now].lc); }}int main(){ root=len=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d%d",&tr[i].d[0],&tr[i].d[1]); root=bt(1,n,0);len=n; while(m--) { int op;int x,y; scanf("%d%d%d",&op,&x,&y); if(op==1 && root==0) { root=len=1;tr[1].id=0; tr[1].mx[0]=tr[1].mn[0]=tr[1].d[0]=x; tr[1].mx[1]=tr[1].mn[1]=tr[1].d[1]=y; } else if(op==1 && root!=0) { len++; tr[len].mx[0]=tr[len].mn[0]=tr[len].d[0]=x; tr[len].mx[1]=tr[len].mn[1]=tr[len].d[1]=y; cmpd=0; ins(len); } else { minn=INF;nowx=x;nowy=y; solmin(root); printf("%d\n",minn); } } return 0;}
阅读全文
0 0
- [BZOJ2648]SJY摆棋子(kd-tree)
- [bzoj2648][kd-tree]SJY摆棋子
- bzoj2648 SJY摆棋子【KD-tree模板】
- bzoj2648&2716 SJY摆棋子 (Kd-Tree)
- [BZOJ2648]SJY摆棋子(KD-tree+讲解)
- 【bzoj2648】【sjy摆棋子】【kd树】
- [bzoj2648][kd树]SJY摆棋子
- BZOJ2648 SJY摆棋子 KD树
- Bzoj2648:SJY摆棋子:K-D-Tree
- bzoj2648 SJY摆石子 kd-tree
- BZOJ2648 SJY摆棋子
- bzoj2648 SJY摆棋子
- 【BZOJ2648】SJY摆棋子
- bzoj2648 SJY摆棋子
- 【BZOJ2648】SYJ摆棋子 KD-Tree
- HYSBZ2648-SJY摆棋子(kd-tree)
- [BZOJ]2648 SJY摆棋子 KD-Tree
- bzoj 2648: SJY摆棋子 (KD-tree)
- 【esp8266】史上最详细的Arduino uno R3接入机智云教程
- 8
- Error:java: 服务配置文件不正确, 或构造处理程序对象javax.annotation.processing.Processor: Provider org.antlr.v4.runtime
- python计算txt文本有多少单词
- okcoinapi----现货美元版本
- [bzoj2648][kd-tree]SJY摆棋子
- FP风格以及并发的快速排序
- 9、ssm整合activeMQ、JAVAMail实现邮件异步注册和登陆功能
- 【跳棋、跳房子】与单调队列
- NKOJ 2409 田忌赛马 (DP)
- mysql root忘记密码重置
- 高数 03.05函数的极值与最大值最小值
- 使用 EasyUI 实现 MySQL 数据 简单的 增删改查
- 关于mysql的一些操作指令基础1-1