結果
| 問題 |
No.2436 Min Diff Distance
|
| コンテスト | |
| ユーザー |
Kude
|
| 提出日時 | 2023-08-19 01:11:15 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,790 ms / 2,000 ms |
| コード長 | 3,610 bytes |
| コンパイル時間 | 2,963 ms |
| コンパイル使用メモリ | 237,564 KB |
| 最終ジャッジ日時 | 2025-02-16 11:16:27 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 23 |
ソースコード
#include<bits/stdc++.h>
namespace {
#pragma GCC diagnostic ignored "-Wunused-function"
#include<atcoder/all>
#pragma GCC diagnostic warning "-Wunused-function"
using namespace std;
using namespace atcoder;
#define rep(i,n) for(int i = 0; i < (int)(n); i++)
#define rrep(i,n) for(int i = (int)(n) - 1; i >= 0; i--)
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
template<class T> bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; } else return false; }
template<class T> bool chmin(T& a, const T& b) { if (b < a) { a = b; return true; } else return false; }
using ll = long long;
using P = pair<int,int>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
template<class T>
vector<T> manhattan_dist_max(vector<pair<T, T>> ps) {
T v1, v2, v3, v4;
v1 = v3 = numeric_limits<T>::max();
v2 = v4 = numeric_limits<T>::min();
for(auto [x, y] : ps) {
T s = x + y;
T t = -x + y;
chmin(v1, s);
chmax(v2, s);
chmin(v3, t);
chmax(v4, t);
}
int n = ps.size();
vector<T> res;
res.reserve(n);
for(auto [x, y] : ps) {
T s = x + y;
T t = -x + y;
res.emplace_back(max({s - v1, v2 - s, t - v3, v4 - t}));
}
return res;
}
template<class T>
vector<T> manhattan_dist_min(const vector<pair<T, T>>& points) {
const int n = points.size();
assert(n >= 2);
struct S {
T x, y;
int i;
};
vector<S> ps(n);
for (int i = 0; i < n; i++) {
auto [x, y] = points[i];
ps[i] = {x + y, -x + y, i};
}
sort(ps.begin(), ps.end(), [](const S& p1, const S& p2) {
return p1.x < p2.x;
});
vector<T> vals(n);
for (int i = 0; i < n; i++) vals[i] = ps[i].y;
sort(vals.begin(), vals.end());
vals.erase(unique(vals.begin(), vals.end()), vals.end());
const int sz = vals.size();
vector<int> ys(n);
for (int i = 0; i < n; i++) {
ys[i] = lower_bound(vals.begin(), vals.end(), ps[i].y) - vals.begin();
}
vector<T> ls(n, -1), rs(n);
auto dist = [&](const S& p1, const S& p2) {
return max(abs(p1.x - p2.x), abs(p1.y - p2.y));
};
for (int i = 1; i < n; i++) rs[0] = rs[i] = dist(ps[0], ps[i]);
struct E {
T x;
bool t;
int i;
bool operator<(const E& rhs) const {
return x < rhs.x || (x == rhs.x && t < rhs.t);
}
};
vector<E> evs;
fenwick_tree<int> ft(sz);
vector<int> cnt(n), yl(n), yr(n);
while(true) {
evs.clear();
for (int i = 0; i < n; i++) if (rs[i] - ls[i] > 1) {
T c = (rs[i] + ls[i]) / 2;
assert(c >= 0);
yl[i] = lower_bound(vals.begin(), vals.end(), ps[i].y - c) - vals.begin();
yr[i] = upper_bound(vals.begin(), vals.end(), ps[i].y + c) - vals.begin();
evs.push_back(E{ps[i].x - c, false, i});
evs.push_back(E{ps[i].x + c, true, i});
}
if (evs.empty()) break;
sort(evs.begin(), evs.end());
int ptr = 0;
for (auto [x, t, i] : evs) {
while(ptr < n && ((!t && ps[ptr].x < x) || (t && ps[ptr].x <= x))) {
ft.add(ys[ptr++], 1);
}
int sm = ft.sum(yl[i], yr[i]);
if (!t) {
cnt[i] = sm;
} else {
assert(cnt[i] + 1 <= sm);
(cnt[i] + 1 == sm ? ls[i] : rs[i]) = (ls[i] + rs[i]) / 2;
}
}
}
vector<T> res(n);
for (int i = 0; i < n; i++) res[ps[i].i] = rs[i];
return res;
}
} int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
vector<pair<int, int>> xy(n);
for(auto& [x, y] : xy) cin >> x >> y;
VI mx = manhattan_dist_max(xy);
VI mn = manhattan_dist_min(xy);
int ans = 2001001001;
rep(i, n) chmin(ans, mx[i] - mn[i]);
cout << ans << '\n';
}
Kude