bzoj 2468 kdtree

来源:互联网 发布:泸州市网络问政平台 编辑:程序博客网 时间:2024/06/05 06:01


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 输出一个最小距离
 
考察知识点kd-tree
kd-tree学习推荐思路和详细讲解
代码参考bloghttp://blog.csdn.net/lych_cys/article/details/50809141
ACcode:
#include <bits/stdc++.h>#define maxn 1000006#define inf 1000000000using namespace std;int n,m,dim,rt,ans;inline int CIN(){    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;}struct node{    int p[2],x[2],y[2];}a[maxn];bool cmp(node x,node y){    return x.p[dim]<y.p[dim];};struct kd_tree{    int c[maxn][2];    node s[maxn],q;    void update(int k){        int l=c[k][0],r=c[k][1];        for(int i=0;i<2;++i){            if(l){                s[k].x[i]=min(s[k].x[i],s[l].x[i]);                s[k].y[i]=max(s[k].y[i],s[l].y[i]);            }            if(r){                s[k].x[i]=min(s[k].x[i],s[r].x[i]);                s[k].y[i]=max(s[k].y[i],s[r].y[i]);            }        }    }    void add(int k,node t){        for(int i=0;i<2;++i)            s[k].x[i]=s[k].y[i]=s[k].p[i]=t.p[i];    }    int dist(node t,int k){        int tmp=0;        for(int i=0;i<2;++i)tmp+=max(0,s[k].x[i]-t.p[i]);        for(int i=0;i<2;++i)tmp+=max(0,t.p[i]-s[k].y[i]);        return tmp;    }    void build(int &k,int l,int r,int now){        k=(l+r)>>1;dim=now;        nth_element(a+l,a+k,a+r+1,cmp);        add(k,a[k]);        if(l<k)build(c[k][0],l,k-1,now^1);        if(k<r)build(c[k][1],k+1,r,now^1);        update(k);    }    void ins(int k,int now){        if(q.p[now]<s[k].p[now])            if(c[k][0])ins(c[k][0],now^1);            else {                c[k][0]=++n;                add(n,q);            }        else            if(c[k][1])ins(c[k][1],now^1);            else{                c[k][1]=++n;                add(n,q);            }        update(k);    }    void qry(int k){        ans=min(ans,abs(s[k].p[0]-q.p[0])+abs(s[k].p[1]-q.p[1]));        int dl=(c[k][0])?dist(q,c[k][0]):inf,dr=(c[k][1])?dist(q,c[k][1]):inf;        if(dl<dr){            if(dl<ans)qry(c[k][0]);            if(dr<ans)qry(c[k][1]);        }        else {            if(dr<ans)qry(c[k][1]);            if(dl<ans)qry(c[k][0]);        }    }}my;int main(){    n=CIN();m=CIN();    for(int i=1;i<=n;++i){        a[i].p[0]=CIN();        a[i].p[1]=CIN();    }    my.build(rt,1,n,0);    for(int i=0;i<m;++i){        int t;        t=CIN();        my.q.p[0]=CIN();        my.q.p[1]=CIN();        if(t==1)my.ins(rt,0);        else{            ans=inf;            my.qry(rt);            printf("%d\n",ans);        }    }    return 0;}


0 0
原创粉丝点击