首页 > 代码库 > BZOJ 2626: JZPFAR

BZOJ 2626: JZPFAR

Description

求平面第\(k\)远的点,\(n\leqslant 10^5\)

Solution

KD-Tree.

用一个堆统计答案即可...

Code

/**************************************************************    Problem: 2626    User: BeiYu    Language: C++    Result: Accepted    Time:16080 ms    Memory:4824 kb****************************************************************/ #include <bits/stdc++.h>using namespace std; typedef long long LL;const int N = 100050;const int M = 2;const int K = 25; 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; } #define lc p[o].ch[0]#define rc p[o].ch[1]#define mid ((l+r)>>1)#define sqr(x) ((x)*(x))  namespace KDTree {    struct Node {        int id,mi[M],mx[M],d[M],ch[2];        Node() {            id=ch[0]=ch[1]=0;            for(int i=0;i<M;i++) mi[i]=mx[i]=d[i]=0;        }    }p[N];         int D,cp,rt,k;Node qp;    int cmp(const Node &a,const Node &b) { return a.d[D]<b.d[D]; }    LL dis2(Node a,Node b) {        LL d=0;        for(int i=0;i<M;i++) d+=sqr((LL)a.d[i]-b.d[i]);        return d;    }    double dis(Node a,Node b) { return sqrt(dis2(a,b)); }    void Update(int o) {        for(int i=0;i<M;i++) p[o].mx[i]=p[o].mi[i]=p[o].d[i];        if(lc) for(int i=0;i<M;i++)            p[o].mx[i]=max(p[o].mx[i],p[lc].mx[i]),p[o].mi[i]=min(p[o].mi[i],p[lc].mi[i]);        if(rc) for(int i=0;i<M;i++)            p[o].mx[i]=max(p[o].mx[i],p[rc].mx[i]),p[o].mi[i]=min(p[o].mi[i],p[rc].mi[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<mid) Build(lc,l,mid-1,(d+1)%M);        if(r>mid) Build(rc,mid+1,r,(d+1)%M);        Update(o);    }    LL S(int o) {        LL res=0;        for(int i=0;i<M;i++) res+=max(sqr((LL)p[o].mx[i]-qp.d[i]),sqr((LL)qp.d[i]-p[o].mi[i]));        return res;    }    struct QNode { LL d2;int id; };    bool operator < (const QNode &a,const QNode &b) { return a.d2==b.d2?a.id<b.id:a.d2>b.d2; }    priority_queue<QNode> q;    void Query(int o) {        if(!o) return;        LL d=dis2(p[o],qp),ll=lc?S(lc):-2,rr=rc?S(rc):-2;        if((QNode) { d,p[o].id } < q.top()) q.pop(),q.push((QNode) { d,p[o].id });        if(ll>rr) {            if(ll>=q.top().d2) Query(lc);            if(rr>=q.top().d2) Query(rc);        } else {            if(rr>=q.top().d2) Query(rc);            if(ll>=q.top().d2) Query(lc);        }    }         int Qur(int k,Node a) {        for(;!q.empty();) q.pop();        for(int i=0;i<k;i++) q.push((QNode) { -1,0 });        qp=a;        Query(rt);        return q.top().id;    }}; using namespace KDTree; int n,m; int main() {    cp=n=in();    for(int i=1;i<=n;i++) {        for(int j=0;j<M;j++) p[i].d[j]=in();        p[i].id=i;    }    Build(rt=1,1,n,0);    for(m=in();m--;) {        Node a=Node();        for(int j=0;j<M;j++) a.d[j]=in();        int k=in();        printf("%d\n",Qur(k,a));    }    return 0;}

  

BZOJ 2626: JZPFAR