QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#385455#5463. Range Closest Pair of Points Queryalpha1022RE 4ms22540kbC++142.7kb2024-04-10 19:24:582024-04-10 19:24:58

Judging History

你现在查看的是最新测评结果

  • [2024-04-10 19:24:58]
  • 评测
  • 测评结果:RE
  • 用时:4ms
  • 内存:22540kb
  • [2024-04-10 19:24:58]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const ll inf = 0x3f3f3f3f3f3f3f3f;

const int N = 2.5e5;
const int B = 500;
const int LG = 28;
const int D = 3;

int n, q;

struct SqrtDecomposition {
  int pos[N + 5];
  ll val[N + 5], sum[B + 5];
  void init(int n) {
    for (int i = 1; i <= n; ++i) pos[i] = (i - 1) / B + 1;
    fill_n(val + 1, n, inf), fill_n(sum + 1, pos[n], inf);
  }
  void insert(int x, ll k) {
    val[x] = min(val[x], k), sum[pos[x]] = min(sum[pos[x]], k);
  }
  ll query(int x) {
    ll ret = inf;
    for (int i = x; i <= min(pos[x] * B, n); ++i) ret = min(ret, val[i]);
    for (int p = pos[x] + 1; p <= pos[n]; ++p) ret = min(ret, sum[p]);
    return ret;
  }
} sd;

int x[N + 5], y[N + 5];
ll dist(ll i, ll j) { return (ll)(x[i] - x[j]) * (x[i] - x[j]) + (ll)(y[i] - y[j]) * (y[i] - y[j]); }
ll id(int x, int y) { return (ll)x << 30 | y; }
unordered_map<ll, pair<int, int>> pos;
int a[N + 5];
vector<int> upd[N + 5];
vector<pair<int, int>> qry[N + 5];
ll ans[N + 5];

int main() {
  scanf("%d%d", &n, &q);
  for (int i = 1; i <= n; ++i) scanf("%d%d", x + i, y + i), a[i] = i;
  for (int k = 0; k < LG; ++k) {
    sort(a + 1, a + n + 1, [&](int i, int j) {
      return id(x[i] >> k, y[i] >> k) < id(x[j] >> k, y[j] << k);
    });
    for (int l = 1, r; l <= n; l = r + 1) {
      ll cur = id(x[a[l]] >> k, y[a[l]] >> k);
      for (r = l; r < n && id(x[a[r + 1]] >> k, y[a[r + 1]] >> k) == cur; ++r);
      sort(a + l, a + r + 1), pos[cur] = {l, r};
      for (int i = l; i < r; ++i)
        for (int j = i + 1; j <= i + D && j <= r; ++j)
          upd[a[j]].push_back(a[i]);
    }
    for (int l = 1, r; l <= n; l = r + 1) {
      ll cur = id(x[a[l]] >> k, y[a[l]] >> k);
      tie(l, r) = pos[cur];
      for (auto [dx, dy] : vector<pair<int, int>>{{-1, 1}, {0, 1}, {1, 1}, {1, 0}}) {
        if (dx == -1 && !(x[a[l]] >> k)) continue;
        ll d = cur + id(dx, dy);
        if (!pos.count(d)) continue;
        auto [dl, dr] = pos[d];
        vector<int> vec(a + l, a + r + 1);
        vec.insert(vec.end(), a + dl, a + dr + 1);
        inplace_merge(vec.begin(), vec.begin() + r - l + 1, vec.end());
        for (int i = 0; i < vec.size(); ++i)
          for (int j = i + 1; j <= i + D && j < vec.size(); ++j)
            upd[vec[j]].push_back(vec[i]);
      }
    }
    unordered_map<ll, pair<int, int>>().swap(pos);
  }
  for (int i = 1; i <= q; ++i) {
    int l, r; scanf("%d%d", &l, &r), qry[r].emplace_back(l, i);
  }
  sd.init(n);
  for (int i = 1; i <= n; ++i) {
    for (int j : upd[i]) sd.insert(j, dist(i, j));
    for (auto [l, id] : qry[i]) ans[id] = sd.query(l);
  }
  for (int i = 1; i <= q; ++i) printf("%lld\n", ans[i]);
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 4ms
memory: 20196kb

input:

5 5
2 4
1 1
3 3
5 1
4 2
1 5
2 3
2 4
3 5
1 3

output:

2
8
8
2
2

result:

ok 5 number(s): "2 8 8 2 2"

Test #2:

score: 0
Accepted
time: 0ms
memory: 22540kb

input:

2 1
1 1
1 1
1 2

output:

0

result:

ok 1 number(s): "0"

Test #3:

score: 0
Accepted
time: 3ms
memory: 20596kb

input:

2 1
1 100000000
100000000 1
1 2

output:

19999999600000002

result:

ok 1 number(s): "19999999600000002"

Test #4:

score: -100
Runtime Error

input:

20000 250000
3 10
5 4
4 7
1 5
2 1
10 6
2 3
8 4
2 1
8 5
9 8
7 7
4 5
2 7
9 4
9 10
3 2
9 5
10 2
9 2
3 1
9 9
6 5
9 5
9 10
9 1
1 2
8 8
3 4
7 6
6 2
6 8
6 6
8 4
10 2
1 1
10 2
8 3
4 4
5 5
5 1
4 9
7 6
6 8
6 4
1 6
10 3
3 2
4 10
6 8
9 7
2 10
7 8
10 7
3 2
5 1
6 4
7 9
1 3
4 9
4 8
9 4
5 2
2 2
9 2
9 2
9 6
6 9
8 7
...

output:


result: