bzoj 2648: SJY摆棋子(kd tree)
来源:互联网 发布:nginx一键安装脚本 编辑:程序博客网 时间:2024/05/16 12:08
kd tree,裸的模板题。初学,看着别人模板敲了一遍,一直wa,但还找不到原因。。
学习资料:
kd 树算法之思路篇:https://zhuanlan.zhihu.com/p/22557068
kd 树算法之详细篇:https://www.joinquant.com/post/2843
上边两篇和下边这篇还是有那么一点地方不同的。
K-D tree 数据结构:http://blog.csdn.net/zhjchengfeng5/article/details/7855241
代码参考:http://www.cnblogs.com/ljh2000-jump/p/5513620.html
#include <stdio.h>#include <algorithm>using namespace std;typedef long long LL;const int MAXN = 1000011;const int inf = 0x7fffffff;int n,m;int nowD;int root;int ans;int ql,qr;struct node{ int Min[2],Max[2]; int d[2]; int l,r;} t[MAXN*2];int getint(){ int w=0,q=0; char c=getchar(); while((c<'0' || c>'9') && c!='-') c=getchar(); if (c=='-') q=1, c=getchar(); while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w;}bool cmp(node q,node qq){ if(q.d[nowD]==qq.d[nowD]) return q.d[!nowD]<qq.d[!nowD]; return q.d[nowD]<qq.d[nowD];}void kd_updata(int now){ if(t[now].l) { if(t[t[now].l].Max[0]>t[now].Max[0]) t[now].Max[0]=t[t[now].l].Max[0]; if(t[t[now].l].Max[1]>t[now].Max[1]) t[now].Max[1]=t[t[now].l].Max[1]; if(t[t[now].l].Min[0]<t[now].Min[0]) t[now].Min[0]=t[t[now].l].Min[0]; if(t[t[now].l].Min[1]<t[now].Min[1]) t[now].Min[1]=t[t[now].l].Min[1]; } if(t[now].r) { if(t[t[now].r].Max[0]>t[now].Max[0]) t[now].Max[0]=t[t[now].r].Max[0]; if(t[t[now].r].Max[1]>t[now].Max[1]) t[now].Max[1]=t[t[now].r].Max[1]; if(t[t[now].r].Min[0]<t[now].Min[0]) t[now].Min[0]=t[t[now].r].Min[0]; if(t[t[now].r].Min[1]<t[now].Min[1]) t[now].Min[1]=t[t[now].r].Min[1]; }}int kd_build(int l,int r,int D){ int mid=(l+r) >> 1; nowD=D; nth_element(t+l+1,t+mid+1,t+r+1,cmp); if(l!=mid) t[mid].l=kd_build(l,mid-1,!D); if(r!=mid) t[mid].r=kd_build(mid+1,r,!D); t[mid].Max[0]=t[mid].Min[0]=t[mid].d[0]; t[mid].Max[1]=t[mid].Min[1]=t[mid].d[1]; kd_updata(mid); return mid;}int dist(int p){ int dis=0; if(ql < t[p].Min[0]) dis+=t[p].Min[0]-ql; if(ql > t[p].Max[0]) dis+=ql-t[p].Max[0]; if(qr < t[p].Min[1]) dis+=t[p].Min[1]-qr; if(qr > t[p].Max[1]) dis+=qr-t[p].Max[1]; return dis;}void kd_query(int p){ int dl,dr,d0; d0=abs(t[p].d[0]-ql)+abs(t[p].d[1]-qr); if(d0<ans) ans=d0; if(t[p].l) dl=dist(t[p].l); else dl=inf; if(t[p].r) dr=dist(t[p].r); else dr=inf; if(dl<dr) { if(dl<ans) kd_query(t[p].l); if(dr<ans) kd_query(t[p].r); } else { if(dr<ans) kd_query(t[p].r); if(dl<ans) kd_query(t[p].l); }}inline void kd_insert(int now){ int p=root,D=0; while(true) { if(t[now].Max[0]>t[p].Max[0]) t[p].Max[0]=t[now].Max[0]; if(t[now].Max[1]>t[p].Max[1]) t[p].Max[1]=t[now].Max[1]; if(t[now].Min[0]<t[p].Min[0]) t[p].Min[0]=t[now].Min[0]; if(t[now].Min[1]<t[p].Min[1]) t[p].Min[1]=t[now].Min[1]; if(t[now].d[D]>=t[p].d[D]) { if(!t[p].r) { t[p].r=now; return; } else p=t[p].r; } else { if(!t[p].l) { t[p].l=now; return ; } else p=t[p].l; } D=!D; }}int main(){ scanf("%d %d",&n,&m); for(int i=1; i<=n; i++) scanf("%d %d",&t[i].d[0],&t[i].d[1]); root=kd_build(1,n,0); int x,y,z; for(int i=1; i<=m; i++) { scanf("%d %d %d",&x,&y,&z); if(x==1) { ++n; t[n].Max[0]=t[n].Min[0]=t[n].d[0]=y; t[n].Max[1]=t[n].Min[1]=t[n].d[1]=z; kd_insert(n); } else { ans=inf; ql=y,qr=z; kd_query(root); printf("%d\n",ans); } } return 0;}
阅读全文
0 0
- [BZOJ]2648 SJY摆棋子 KD-Tree
- bzoj 2648: SJY摆棋子 (KD-tree)
- bzoj 2648: SJY摆棋子(kd tree)
- [BZOJ2648]SJY摆棋子(kd-tree)
- HYSBZ2648-SJY摆棋子(kd-tree)
- [KD-TREE] BZOJ 2648 SJY摆棋子 & BZOJ 2716 [Violet 3]天使玩偶
- BZOJ 2648/2716 SJY摆棋子/[Violet 3]天使玩偶 kd tree
- bzoj2648&2716 SJY摆棋子 (Kd-Tree)
- [BZOJ2648]SJY摆棋子(KD-tree+讲解)
- [bzoj2648][kd-tree]SJY摆棋子
- bzoj2648 SJY摆棋子【KD-tree模板】
- BZOJ 2648 SJY摆棋子
- BZOJ 2648 SJY摆棋子
- BZOJ 2648 SJY摆棋子
- BZOJ 2648 SJY摆棋子 K-Dimensional-Tree
- BZOJ 2648 SJY摆棋子 K-D Tree
- 【34.25%】【BZOJ 2648】SJY摆棋子
- 【BZOJ 2648/2716】SJY摆棋子
- layui使用
- hdu1072 Nightmare
- 改写某个模拟器的go语言源码遇到的问题
- 坚果云与Git
- springmvc与mybatis整合中的问题
- bzoj 2648: SJY摆棋子(kd tree)
- 51nod 1222 最小公倍数计数
- 小数据的处理
- Ubuntu使用docker安装redmine
- $.each(srcData, function(i, oneData){});
- php require
- Matlab2017a中英文界面设置
- C学习笔记--链表
- 关键字:static和extern(在C和C++中)