BZOJ 2648 SJY摆棋子 K-Dimensional-Tree

来源:互联网 发布:an软件 编辑:程序博客网 时间:2024/05/17 02:07

题目大意:给定平面上的n个点,定义距离为曼哈顿距离,支持下列操作:

1.插入一个点

2.查询离一个点最近的点的距离

Hint说KDTree【可以】过,那么不写KDT还能写啥= =

我的CDQ分治可是T掉了啊= =

记住KDT发生TLE事件的时候不一定是常数问题 有可能写挂了= =(这不和莫队一样么233

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 500500#define INF 0x3f3f3f3fusing namespace std;struct Point{int x,y;friend istream& operator >> (istream &_,Point &p){scanf("%d%d",&p.x,&p.y);return _;}friend int Distance(const Point &p1,const Point &p2){return abs(p1.x-p2.x) + abs(p1.y-p2.y) ;}}points[M];int n,m;bool Compare_x(const Point &p1,const Point &p2){return p1.x < p2.x ;}bool Compare_y(const Point &p1,const Point &p2){return p1.y < p2.y ;}namespace K_Dimensional_Tree{struct abcd{abcd *ls,*rs;Point p;int x1,y1,x2,y2;abcd() {}abcd(const Point &_):p(_){ls=rs=0x0;x1=x2=p.x;y1=y2=p.y;}void Push_Up(abcd *x){x1=min(x1,x->x1);y1=min(y1,x->y1);x2=max(x2,x->x2);y2=max(y2,x->y2);}int Min_Distance(const Point &p){int re=0;if(p.x<x1) re+=x1-p.x;if(p.x>x2) re+=p.x-x2;if(p.y<y1) re+=y1-p.y;if(p.y>y2) re+=p.y-y2;return re;}/*int Max_Distance(const Point &p){int re=0;re+=max(p.x-x1,x2-p.x);re+=max(p.y-y1,y2-p.y);return re;}*/}mempool[M],*C=mempool,*root;void Build_Tree(abcd *&x,int l,int r,bool flag){if(l>r)return ;int mid=l+r>>1;nth_element(points+l,points+mid,points+r+1,flag?Compare_y:Compare_x);x=new abcd(points[mid]);Build_Tree(x->ls,l,mid-1,flag^1);Build_Tree(x->rs,mid+1,r,flag^1);if(x->ls) x->Push_Up(x->ls);if(x->rs) x->Push_Up(x->rs);}void Insert(abcd *&x,const Point &p,bool flag){if(!x){x=new abcd(p);return ;}if( (flag?Compare_y:Compare_x)(p,x->p) ){Insert(x->ls,p,flag^1);x->Push_Up(x->ls);}else{Insert(x->rs,p,flag^1);x->Push_Up(x->rs);}}void Get_Min(abcd *x,const Point &p,int &ans){ans=min(ans,Distance(x->p,p));int l_dis=x->ls?x->ls->Min_Distance(p):INF;int r_dis=x->rs?x->rs->Min_Distance(p):INF;if(l_dis<r_dis){if( x->ls && l_dis<ans )Get_Min(x->ls,p,ans);if( x->rs && r_dis<ans )Get_Min(x->rs,p,ans);}else{if( x->rs && r_dis<ans )Get_Min(x->rs,p,ans);if( x->ls && l_dis<ans )Get_Min(x->ls,p,ans);}}}int main(){using namespace K_Dimensional_Tree;int i,o;Point p;cin>>n>>m;for(i=1;i<=n;i++)cin>>points[i];Build_Tree(root,1,n,0);for(i=1;i<=m;i++){scanf("%d",&o);cin>>p;if(o==1)Insert(root,p,0);else{int ans=INF;Get_Min(root,p,ans);printf("%d\n",ans);}}return 0;}


0 0
原创粉丝点击