ABC215 F - Dist Max 2(二分答案)
阿新 • • 發佈:2021-10-05
目錄
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; }