luogu P1429 平面最近点对
调半个晚上...一个板子整这么慢
之前网上一直没看明白 今天终于完事了
首先分治很容易想到 这里按x分
考虑暴力的复杂度极限 就是所有的点到中线距离相等
可以看出上下相距很远的点显然不对
那么这个很远是什么呢 是不是大于当前答案d的都可以舍去..
所以我们可以对于到中线的距离小于d的每个点找到与它y轴距离小于d的点更新答案(主要是因为画个圆太麻烦了)
然后这个可以证明每个点匹配的个数是常数 就需要用到网上流传的那个图了
至于为什么可以考虑如果一侧的d*d正方形里如果有四个以上的点那么最小值一定可以更小
代码真好写...
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<queue> 6 #include<iostream> 7 #define ms(a,b) memset(a,b,sizeof a) 8 #define rep(i,a,n) for(int i = a;i <= n;i++) 9 #define per(i,n,a) for(int i = n;i >= a;i--) 10 #define inf 2147483647 11 using namespace std; 12 typedef long long ll; 13 ll read() { 14 ll as = 0,fu = 1; 15 char c = getchar(); 16 while(c < '0' || c > '9') { 17 if(c == '-') fu = -1; 18 c = getchar(); 19 } 20 while(c >= '0' && c <= '9') { 21 as = as * 10 + c - '0'; 22 c = getchar(); 23 } 24 return as * fu; 25 } 26 const int N = 200003; 27 //head 28 typedef double D; 29 #define eps 1e-8 30 struct node { 31 D x,y; 32 D len() {return sqrt(x*x+y*y);} 33 node operator - (const node &o) const { 34 return (node){x-o.x,y-o.y}; 35 } 36 bool operator < (const node &o) const { 37 return x < o.x; 38 } 39 }p[N]; 40 int n; 41 42 //[l,r) 43 D solve(int l,int r) { 44 if(r - l == 1) return 3e20; 45 int m = l+r >> 1; 46 D xmid = (p[m].x + p[m - 1].x) / 2.0; 47 D d = min(solve(l,m),solve(m,r)); 48 int topb = 0,topc = 0; 49 static node a[N],b[N],c[N]; 50 int L = l,R = m; 51 int curb = 0,curc = 0; 52 rep(i,l,r - 1) { 53 if(L < m && (R == r || p[L].y < p[R].y) ) { 54 a[i] = p[L++]; 55 if(xmid - a[i].x < d) b[topb++] = a[i]; 56 } else { 57 a[i] = p[R++]; 58 if(a[i].x - xmid < d) c[topc++] = a[i]; 59 } 60 } 61 62 rep(i,l,r - 1) p[i] = a[i]; 63 while(curb < topb || curc < topc) { 64 if(curb < topb && (curc == topc || b[curb].y < c[curc].y)) { 65 per(k,curc - 1,0) { 66 if(b[curb].y - c[k].y > d) break; 67 d = min(d,(c[k] - b[curb]).len()); 68 } 69 curb++; 70 } else { 71 per(k,curb - 1,0) { 72 if(c[curc].y - b[k].y > d) break; 73 d = min(d,(b[k] - c[curc]).len()); 74 } 75 curc++; 76 } 77 } 78 return d; 79 } 80 81 int main() { 82 n = read(); 83 rep(i,1,n) scanf("%lf%lf",&p[i].x,&p[i].y); 84 sort(p+1,p+n+1); 85 printf("%.4f\n",solve(1,n+1)); 86 return 0; 87 }
> 别忘了 总有人在等着你