BZOJ 2626 & KDtree
题意:
二维平面n个点 每次给出一个点询问距离第k小的点.
SOL:
kdtree裸题,抄了一发别人的模板...二维割起来还是非常显然的.膜rzz的论文.
不多说了吧....
Code:
/*========================================================================== # Last modified: 2016-03-18 20:26 # Filename: 2626.cpp # Description: ==========================================================================*/ #define me AcrossTheSky #include <cstdio> #include <cmath> #include <ctime> #include <string> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <set> #include <map> #include <stack> #include <queue> #include <vector> #define lowbit(x) (x)&(-x) #define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) #define FORP(i,a,b) for(int i=(a);i<=(b);i++) #define FORM(i,a,b) for(int i=(a);i>=(b);i--) #define ls(a,b) (((a)+(b)) << 1) #define rs(a,b) (((a)+(b)) >> 1) #define getlc(a) ch[(a)][0] #define getrc(a) ch[(a)][1] #define maxn 100000 #define maxm 100000 #define pi 3.1415926535898 #define _e 2.718281828459 #define INF 1070000000 using namespace std; typedef long long LL; typedef unsigned long long uLL; template<class T> inline void read(T& num) { bool start=false,neg=false; char c; num=0; while((c=getchar())!=EOF) { if(c=='-') start=neg=true; else if(c>='0' && c<='9') { start=true; num=num*10+c-'0'; } else if(start) break; } if(neg) num=-num; } /*==================split line==================*/ int flag; struct node{ int id; LL x,y; void in(int i){ read(x); read(y); id=i; } bool operator<(const node& a)const{ if(!flag) return x<a.x; return y<a.y; } }p[maxn]; LL sqr(LL x){return x*x;} LL dist(node a,node b){return sqr(a.x-b.x)+sqr(a.y-b.y);} struct cpt{ LL dis; int id; bool operator<(const cpt &a)const{ if(dis!=a.dis) return dis>a.dis; return id<a.id; } }; priority_queue<cpt> q; struct KD{ LL minv[2],maxv[2]; LL dis(node p){ LL x=max(abs(p.x-minv[0]),abs(p.x-maxv[0])); LL y=max(abs(p.y-minv[1]),abs(p.y-maxv[1])); return sqr(x)+sqr(y); } KD operator+(const KD &a){ KD c; c.minv[0]=min(minv[0],a.minv[0]); c.minv[1]=min(minv[1],a.minv[1]); c.maxv[0]=max(maxv[0],a.maxv[0]); c.maxv[1]=max(maxv[1],a.maxv[1]); return c; } }; struct KDtree{ node p;KD c; }tree[maxn]; int n,m,kth,ch[maxn][2],tot; int build(int l,int r,int k){ int x=++tot; flag=k; int mid=rs(l,r); nth_element(p+l,p+mid,p+r+1); tree[x].p=p[mid]; tree[x].c.minv[0]=tree[x].c.maxv[0]=tree[x].p.x; tree[x].c.minv[1]=tree[x].c.maxv[1]=tree[x].p.y; if (l<=mid-1){ ch[x][0]=build(l,mid-1,k^1); tree[x].c=tree[x].c+tree[ch[x][0]].c; } if (mid+1<=r){ ch[x][1]=build(mid+1,r,k^1); tree[x].c=tree[x].c+tree[ch[x][1]].c; } return x; } void ask(int x,node a,int k){ cpt tmp=(cpt){dist(tree[x].p,a),tree[x].p.id}; int lc=ch[x][0],rc=ch[x][1]; flag=k; if (q.size()<kth) q.push(tmp); else if (tmp<q.top()){q.pop(); q.push(tmp);} if (a<tree[x].p) swap(lc,rc); if (lc && (q.size()<kth || tree[lc].c.dis(a)>=q.top().dis)) ask(lc,a,k^1); if (rc && (q.size()<kth || tree[rc].c.dis(a)>=q.top().dis)) ask(rc,a,k^1); } int main(){ //freopen("a.in","r",stdin); read(n); FORP(i,1,n) p[i].in(i); build(1,n,0); int m; read(m); FORP(i,1,m){ node a; a.in(i); read(kth); while (!q.empty()) q.pop(); ask(1,a,0); printf("%d\n",q.top().id); } }
Sometimes it s the very people who no one imagines anything of. who do the things that no one can imagine.