ABC215 F - Dist Max 2(二分答案)

目录

Description

\(n\) 个点,每个点之间的距离为 \(min(|x_i-x_j|,|y_i-y_j|)\),求点与点之间的最大值

State

\(2<=n<=2*10^5\)

\(0<=x_i,y_i<=10^9\)

Input

3
0 3
3 1
4 10

Output

4

Solution

题目还是很巧妙地,知道了用二分就已经解决一半了

由于两点之间的距离 \(min(|x_i-x_j|,|y_i-y_j|)\),所以如果横坐标两点的距离确定后,那么可以排除很多点,只留下 \(|y_i-y_j|<|x_i-x_j|\) 的那些 \(j\)

上面的思路提供了一个突破点:距离;

将横坐标升序排列,二分距离记为 \(x\),如果存在 \(j\) 使得 \(|x_j-x_i|>=x\),(\([j,n]\) 上的点都会满足),之后如果有 \(|y_k-y_i|>=x\)\(k∈[j,n]\)),则 \(x\) 可以被确定为答案


Code

const int N = 1e6 + 5;
 
    int n, m, k, _;
    pll a[N];
    ll maxx[N];
    ll minn[N];

bool check(ll x)
{
    int p = 1;
    for(int i = 1; i <= n;){
        if(a[i].fi - a[p].fi >= x){
            if(maxx[i] - a[p].se >= x) return 1;
            if(a[p].se - minn[i] >= x) return 1;
            p ++;
        }
        else i ++;
    }
    return 0;
}

signed main()
{
    //IOS;
    while(~ sd(n)){
        rep(i, 1, n){
            sll2(a[i].fi, a[i].se);
        }
        sort(a + 1, a + 1 + n);
        maxx[n] = minn[n] = a[n].se;
        for(int i = n - 1; i; i --){
            maxx[i] = max(maxx[i + 1], a[i].se);
            minn[i] = min(minn[i + 1], a[i].se);
        }
        ll l = 0, r = 2e9, ans = 0;
        while(r >= l){
            ll mid = l + r >> 1;
            if(check(mid)){
                ans = mid;
                l = mid + 1;
            } 
            else{
                r = mid - 1;
            }
        }
        pll(ans);
    }
    //PAUSE;
    return 0;
}
posted @ 2021-10-05 11:14  Bcoi  阅读(127)  评论(0)    收藏  举报