BZOJ 2648 SJY摆棋子
2016-03-31 19:03
344 查看
kd树模板。这玩意儿我现在理解的还不是很透彻因此暂时没有更多的解释。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define maxn 505000 #define inf 1000000007 using namespace std; struct kd { int mx[3],mi[3],d[3]; int l,r; }t[maxn<<1]; struct point { int num[3]; }p[maxn],regis; int n,m,type,x,y,root,D,ans; bool cmp(point a,point b) { return a.num[D]<b.num[D]; } inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } void update(int k) { int ls=t[k].l,rs=t[k].r; for (int i=0;i<=1;i++) { if (ls) t[k].mx[i]=max(t[k].mx[i],t[ls].mx[i]); if (ls) t[k].mi[i]=min(t[k].mi[i],t[ls].mi[i]); if (rs) t[k].mx[i]=max(t[k].mx[i],t[rs].mx[i]); if (rs) t[k].mi[i]=min(t[k].mi[i],t[rs].mi[i]); } } int build(int left,int right,int split) { D=split;int mid=(left+right)>>1; nth_element(p+left,p+mid,p+right+1,cmp); for (int i=0;i<=1;i++) { t[mid].mx[i]=p[mid].num[i]; t[mid].mi[i]=t[mid].mx[i]; t[mid].d[i]=t[mid].mi[i]; } if (left<mid) t[mid].l=build(left,mid-1,split^1); if (mid<right) t[mid].r=build(mid+1,right,split^1); update(mid); return mid; } void insert(int now,int split) { if (regis.num[split]>=t[now].d[split]) { if (t[now].r) insert(t[now].r,split^1); else { t[now].r=++n; for (int i=0;i<=1;i++) { t .mx[i]=regis.num[i]; t .mi[i]=regis.num[i]; t .d[i]=regis.num[i]; } } } else { if (t[now].l) insert(t[now].l,split^1); else { t[now].l=++n; for (int i=0;i<=1;i++) { t .mx[i]=regis.num[i]; t .mi[i]=regis.num[i]; t .d[i]=regis.num[i]; } } } update(now); } int getdis(int k) { int tmp=0; for(int i=0;i<2;i++) tmp+=max(0,t[k].mi[i]-regis.num[i]); for(int i=0;i<2;i++) tmp+=max(0,regis.num[i]-t[k].mx[i]); return tmp; } void ask(int now,int split) { int d0,dl,dr; d0=abs(t[now].d[0]-regis.num[0])+abs(t[now].d[1]-regis.num[1]); ans=min(ans,d0); if (t[now].l) dl=getdis(t[now].l);else dl=inf; if (t[now].r) dr=getdis(t[now].r);else dr=inf; if (dl<dr) { if (dl<ans) ask(t[now].l,split^1); if (dr<ans) ask(t[now].r,split^1); } else { if (dr<ans) ask(t[now].r,split^1); if (dl<ans) ask(t[now].l,split^1); } } int main() { n=read();m=read(); for (int i=1;i<=n;i++) { x=read();y=read(); p[i].num[0]=x;p[i].num[1]=y; } root=build(1,n,0); for (int i=1;i<=m;i++) { type=read();x=read();y=read(); regis.num[0]=x;regis.num[1]=y; if (type==1) insert(root,0); else { ans=inf; ask(root,0); printf("%d\n",ans); } } return 0; }
相关文章推荐
- JavaScript之DOM-3 选取元素(通过 HTML 选取元素、通过 CSS选取元素、其他选取)
- OpenCV安装
- BeestCoder #76
- Masonry - 自动布局
- MFC-利用内存映射文件来读写文件
- 在线评测的网站
- 论软件架构师的基本素养: 三要和三不要
- UIBezierPath - 贝塞尔曲线
- Spring事务Transaction配置的五种注入方式详解
- alpha预乘
- I.MX6Q学习笔记——L3.0.35_4.1.0安装配置(ubuntu14.04)
- NUGI中摄像机问题
- 【Data Algorithms_Recipes for Scaling up with Hadoop and Spark】Chapter 13 k-Nearest Neighbors
- CUDA编程(四)并行化我们的程序
- 探讨web前端性能分析
- 百度地图
- Ruby--如何处理csv文件?
- PHPCMS 二次开发技巧
- 剑指 offer代码解析——面试题39二叉树的深度
- 剑指 offer代码解析——面试题39二叉树的深度