4520: [Cqoi2016]K远点对
Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1285 Solved: 708
[Submit][Status][Discuss]
Description
已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对。
Input
输入文件第一行为用空格隔开的两个整数 N, K。接下来 N 行,每行两个整数 X,Y,表示一个点
的坐标。1 < = N < = 100000, 1 < = K < = 100, K < = N*(N−1)/2 , 0 < = X, Y < 2^31。
Output
输出文件第一行为一个整数,表示第 K 远点对的距离的平方(一定是个整数)。
Sample Input
10 5
0 0
0 1
1 0
1 1
2 0
2 1
1 2
0 2
3 0
3 1
0 0
0 1
1 0
1 1
2 0
2 1
1 2
0 2
3 0
3 1
Sample Output
9
HINT
Source
kd-tree可以查询每个点到其他点的距离。
我们求出每两个点间的距离,随后求出第2*k大值即可。
用优先队列维护前2*k大值,在kd-tree上查询并修改即可。

1 #include<iostream>
2 #include<cstring>
3 #include<cstdlib>
4 #include<cstdio>
5 #include<cmath>
6 #include<algorithm>
7 #include<queue>
8 #define ll long long
9 #define maxn 100005
10 using namespace std;
11 inline int read() {
12 int x=0,f=1;char ch=getchar();
13 for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
14 for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
15 return x*f;
16 }
17 int nowd=0,rt,n,k;
18 struct node {ll d[2],mx[2],mn[2],l,r;}t[maxn];
19 bool cmp(node t1,node t2) {return t1.d[nowd]<t2.d[nowd];}
20 priority_queue<ll,vector<ll>,greater<ll> >q;ll cnt=0;
21 void pushup(int x) {
22 int l=t[x].l,r=t[x].r;
23 if(l) {
24 t[x].mx[0]=max(t[x].mx[0],t[l].mx[0]);
25 t[x].mx[1]=max(t[x].mx[1],t[l].mx[1]);
26 t[x].mn[0]=min(t[x].mn[0],t[l].mn[0]);
27 t[x].mn[1]=min(t[x].mn[1],t[l].mn[1]);
28 }
29 if(r) {
30 t[x].mx[0]=max(t[x].mx[0],t[r].mx[0]);
31 t[x].mx[1]=max(t[x].mx[1],t[r].mx[1]);
32 t[x].mn[0]=min(t[x].mn[0],t[r].mn[0]);
33 t[x].mn[1]=min(t[x].mn[1],t[r].mn[1]);
34 }
35 }
36 int build(int l,int r,bool D) {
37 int mid=l+r>>1;nowd=D;
38 nth_element(t+l,t+mid,t+r+1,cmp);
39 if(l<mid) t[mid].l=build(l,mid-1,!D);
40 if(r>mid) t[mid].r=build(mid+1,r,!D);
41 t[mid].mx[0]=t[mid].mn[0]=t[mid].d[0];
42 t[mid].mx[1]=t[mid].mn[1]=t[mid].d[1];
43 pushup(mid);
44 return mid;
45 }
46 ll dis(int x,int y) {return (t[x].d[0]-t[y].d[0])*(t[x].d[0]-t[y].d[0])+(t[x].d[1]-t[y].d[1])*(t[x].d[1]-t[y].d[1]);}
47 ll gdis(int x,int y) {
48 return max((t[x].mn[0]-t[y].d[0])*(t[x].mn[0]-t[y].d[0]),(t[x].mx[0]-t[y].d[0])*(t[x].mx[0]-t[y].d[0]))+max((t[x].mn[1]-t[y].d[1])*(t[x].mn[1]-t[y].d[1]),(t[x].mx[1]-t[y].d[1])*(t[x].mx[1]-t[y].d[1]));
49 }
50 void query(int x,int y) {
51 if(!x) return;
52 ll now=dis(x,y);
53 if(now>q.top()) {q.pop();q.push(now);}
54 ll dl=0,dr=0;
55 if(t[x].l) dl=gdis(t[x].l,y);if(t[x].r) dr=gdis(t[x].r,y);
56 if(dl>dr) {
57 if(dl>q.top()) query(t[x].l,y);
58 if(dr>q.top()) query(t[x].r,y);
59 }
60 else {
61 if(dr>q.top()) query(t[x].r,y);
62 if(dl>q.top()) query(t[x].l,y);
63 }
64 }
65 int main() {
66 n=read();k=read();
67 for(int i=1;i<=n;i++) t[i].d[0]=read(),t[i].d[1]=read();
68 rt=build(1,n,0);
69 for(int i=1;i<=k*2;i++) q.push(0);
70 for(int i=1;i<=n;i++) query(rt,i);
71 printf("%lld\n",q.top());
72 }
来源:https://www.cnblogs.com/wls001/p/9708908.html
