結果

問題 No.2436 Min Diff Distance
ユーザー KudeKude
提出日時 2023-08-19 20:19:32
言語 C++23
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 144 ms / 2,000 ms
コード長 4,174 bytes
コンパイル時間 3,980 ms
コンパイル使用メモリ 285,556 KB
実行使用メモリ 11,676 KB
最終ジャッジ日時 2023-08-19 20:19:39
合計ジャッジ時間 7,166 ms
ジャッジサーバーID
(参考情報)
judge13 / judge11
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,376 KB
testcase_01 AC 1 ms
4,376 KB
testcase_02 AC 2 ms
4,380 KB
testcase_03 AC 129 ms
11,008 KB
testcase_04 AC 129 ms
11,028 KB
testcase_05 AC 127 ms
10,908 KB
testcase_06 AC 131 ms
10,912 KB
testcase_07 AC 144 ms
10,924 KB
testcase_08 AC 129 ms
11,008 KB
testcase_09 AC 2 ms
4,380 KB
testcase_10 AC 1 ms
4,380 KB
testcase_11 AC 85 ms
11,676 KB
testcase_12 AC 44 ms
10,148 KB
testcase_13 AC 84 ms
8,556 KB
testcase_14 AC 14 ms
4,376 KB
testcase_15 AC 125 ms
11,000 KB
testcase_16 AC 57 ms
6,964 KB
testcase_17 AC 107 ms
9,972 KB
testcase_18 AC 97 ms
9,560 KB
testcase_19 AC 116 ms
10,116 KB
testcase_20 AC 100 ms
8,068 KB
testcase_21 AC 33 ms
5,380 KB
testcase_22 AC 14 ms
4,380 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#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(const 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);
  }
  vector<T> res(ps.size());
  int i = 0;
  for(auto [x, y] : ps) {
    T s = x + y;
    T t = -x + y;
    res[i++] = max({s - v1, v2 - s, t - v3, v4 - t});
  }
  return res;
}

template<class S, auto e, auto op, bool dual=false, bool cursor_indexing=true>
struct BIT {
  vector<S> d;
  int n;
  template<class... Args>
  BIT(auto&&... args) : d(forward<decltype(args)>(args)...), n(d.size()) {
    if constexpr (dual) reverse(d.begin(), d.end());
    for (int i = 1; i < n; i++) {
      int j = i + (i & -i);
      if (j < n) d[j] = op(d[j], d[i]);
    }
  }
  BIT(int n) : d(n, e()), n(n) {}
  void apply(int i, S x) {
    if constexpr (cursor_indexing) {
      assert(0 <= i && i <= n);
      if constexpr (dual) i = n - i;
    } else {
      assert(0 <= i && i < n);
      if constexpr (dual) i = n - 1 - i;
    }
    if (i == 0) {
      if (n > 0) d[i] = op(d[i], x);
    } else {
      while (i < n) {
        d[i] = op(d[i], x);
        i += i & -i;
      }
    }
  }
  S sum(int i) {
    if constexpr (cursor_indexing) {
      assert(0 <= i && i <= n);
      if constexpr (dual) i = n - i;
      if (i == 0) return e();
      i--;
    } else {
      assert(0 <= i && i < n);
      if constexpr (dual) i = n - 1 - i;
    }
    S res = d[i];
    while (i) {
      i -= i & -i;
      res = op(res, d[i]);
    }
    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 {
    pair<T, T> p;
    int i;
  };
  vector<S> ps(n);
  for (int i = 0; i < n; i++) ps[i] = {points[i], i};
  sort(ps.begin(), ps.end(), [](const S& p1, const S& p2) {
    return p1.p.first < p2.p.first;
  });
  vector<T> vals(n);
  for (int i = 0; i < n; i++) vals[i] = ps[i].p.second;
  sort(vals.begin(), vals.end());
  vals.erase(unique(vals.begin(), vals.end()), vals.end());
  const int sz = vals.size();

  constexpr T inf_min = numeric_limits<T>::min() / 2;
  constexpr T inf_max = numeric_limits<T>::max() / 2;
  vector<T> ans(n, inf_max);
  vector<int> y_id(n);
  auto e = []{ return inf_min; };
  auto op = [](T x, T y) { return max(x, y); };
  BIT<T, e, op, false, false> bt1(sz);
  BIT<T, e, op, true, false> bt2(sz);
  for (int i = 0; i < n; i++) {
    auto [x, y] = ps[i].p;
    y_id[i] = lower_bound(vals.begin(), vals.end(), y) - vals.begin();
    chmin(ans[ps[i].i], min(
      x + y - bt1.sum(y_id[i]),
      x - y - bt2.sum(y_id[i])
    ));
    bt1.apply(y_id[i], x + y);
    bt2.apply(y_id[i], x - y);
  }
  bt1.d.assign(sz, e());
  bt2.d.assign(sz, e());
  for (int i = n - 1; i >= 0; i--) {
    auto [x, y] = ps[i].p;
    chmin(ans[ps[i].i], min(
      -bt2.sum(y_id[i]) - (x + y),
      -bt1.sum(y_id[i]) - (x - y)
    ));
    bt2.apply(y_id[i], -(x + y));
    bt1.apply(y_id[i], -(x - y));
  }
  return ans;
}


} 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';
}
0