26pts

P7883 平面最近点对(加强加强版)

koobee @ 2023-04-22 11:20:25

26pts

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
long long n, d=2e14;
struct node{
    int x, y;
} a[N], b[N], c[N];
bool cmp(node x, node y){
    return x.x < y.x;
}
bool cnp(node x, node y){
    return x.y < y.y;
}
long long dis(int a, int b, int c, int d){
    return 1ll * (a-c) * (a-c) + 1ll * (b-d) * (b-d);
}
long long merge(int l, int r){
    if(l == r) return d;
    int mid = (l + r) / 2, cnt = 0, x = l, y = mid + 1, v = a[mid].x, sz = l-1;
    d = min(d, min(merge(l, mid), merge(mid+1, r)));
    while(x <= mid && y <= r){
        if(a[x].y <= a[y].y) c[++sz] = a[x++];
        else c[++sz] = a[y++];
    }
    for(int k = x; k <= mid; k++) c[++sz] = a[k];
    for(int k = y; k <= r; k++) c[++sz] = a[k];
    for(int k = l; k <= r; k++) a[k] = c[k];
    for(int i = l; i <= r; i++)
        if(fabs(v - a[i].x) < d)
            b[++cnt] = a[i];
    for(int i = 1; i <= cnt; i++)
        for(int j = i+1; j <= cnt && b[j].y - b[i].y < d; j++)
            d = min(d, dis(b[i].x, b[i].y, b[j].x, b[j].y));
    return d;
}
int main(){
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin>>n;
    for(int i = 1; i <= n; i++) cin>>a[i].x>>a[i].y;
    sort(a+1, a+1+n, cmp);
    cout<<merge(1, n);
    return 0;
}

by Chenyufeng040525 @ 2023-05-19 22:55:45

@koobee 两个判断小于d那里错了,应该是小于sqrt(d)。这样会把很多无关点算进来,最后tle掉


by koobee @ 2023-05-23 15:59:38

@Chenyufeng040525 谢谢大佬指正~


by _tobi_ @ 2024-03-15 22:14:47

@koobee @Chenyufeng040525 一样的问题,膜拜一下 orz


|