QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#385455 | #5463. Range Closest Pair of Points Query | alpha1022 | RE | 4ms | 22540kb | C++14 | 2.7kb | 2024-04-10 19:24:58 | 2024-04-10 19:24:58 |
Judging History
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]);
}
詳細信息
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 ...