首页 > 代码库 > BZOJ 2648: SJY摆棋子

BZOJ 2648: SJY摆棋子

Descrption

平面求最近点...\(n\leqslant 5\times 10^5\)

Solution

KD-Tree.

双倍经验..BZOJ 2716: [Violet 3]天使玩偶

Code

/**************************************************************    Problem: 2648    User: BeiYu    Language: C++    Result: Accepted    Time:13864 ms    Memory:32560 kb****************************************************************/ #include <bits/stdc++.h>using namespace std; const int N = 1000500;const int M = 2;//const int oo = 0x3f3f3f3f; const int oo = 0x7fffffff; inline int in(int x=0,char s=getchar(),int v=1) { while(s>‘9‘||s<‘0‘) v=s==‘-‘?-1:v,s=getchar();    while(s>=‘0‘&&s<=‘9‘) x=x*10+s-‘0‘,s=getchar();return x*v; } namespace KDTree {    struct Node {        int mi[M],mx[M],d[M],ch[2];        Node() {            ch[0]=ch[1]=0;            for(int i=0;i<M;i++) mx[i]=-oo,mi[i]=oo,d[i]=0;        }    }p[N];    int D,cp,ans,rt;         #define lc p[o].ch[0]    #define rc p[o].ch[1]    #define mid ((l+r)>>1)         int cmp(const Node &a,const Node &b) { return a.d[D]<b.d[D]; }     int dis(const Node &a,const Node &b) {        int res=0;        for(int i=0;i<M;i++) res+=abs(a.d[i]-b.d[i]);        return res;    }    int Newnode(Node a) {        ++cp;p[cp]=Node();        for(int i=0;i<M;i++) p[cp].d[i]=a.d[i];        return cp;    }    void Update(int o) {        for(int i=0;i<M;i++) p[o].mi[i]=p[o].mx[i]=p[o].d[i];        if(lc) for(int i=0;i<M;i++)             p[o].mi[i]=min(p[o].mi[i],p[lc].mi[i]),p[o].mx[i]=max(p[o].mx[i],p[lc].mx[i]);        if(rc) for(int i=0;i<M;i++)            p[o].mi[i]=min(p[o].mi[i],p[rc].mi[i]),p[o].mx[i]=max(p[o].mx[i],p[rc].mx[i]);    }    void Build(int &o,int l,int r,int d) {        D=d,o=mid,nth_element(p+l,p+o,p+r+1,cmp);        if(l<o) Build(lc,l,mid-1,(d+1)%M);        if(r>o) Build(rc,mid+1,r,(d+1)%M);        Update(o);     }    void insert(int &o,int d,Node a) {        if(!o) o=Newnode(p[o]),p[o]=a;        else if(a.d[d]<p[o].d[d]) insert(lc,(d+1)%M,a);        else insert(rc,(d+1)%M,a);//      cout<<o<<" "<<lc<<" "<<rc<<" "<<p[o].d[0]<<" "<<p[o].d[1]<<endl;        Update(o);    }    int S(int o,const Node a) {        int res=0;        for(int i=0;i<M;i++) res+=max(0,p[o].mi[i]-a.d[i])+max(0,a.d[i]-p[o].mx[i]);        return res;    }    void Query(int o,Node a) {        if(!o) return;        ans=min(ans,dis(a,p[o]));        int ll=lc?S(lc,a):oo,rr=rc?S(rc,a):oo;        if(ll<rr) {            if(ll<ans) Query(lc,a);            if(rr<ans) Query(rc,a);        } else {            if(rr<ans) Query(rc,a);            if(ll<ans) Query(lc,a);        }    }    int Qur(Node a) { return ans=oo,Query(rt,a),ans; }}; using namespace KDTree; int n,q; int main() {    cp=n=in(),q=in();    for(int i=1;i<=n;i++) for(int j=0;j<M;j++) p[i].d[j]=in();    Build(rt=1,1,n,0);    for(int i=1;i<=q;i++) {        int opt=in();Node a=Node();        for(int i=0;i<M;i++) a.d[i]=in();        if(opt==1) insert(rt,0,a);        else printf("%d\n",Qur(a));    }return 0;}

  

BZOJ 2648: SJY摆棋子