题解:P9062 [Ynoi2002] Adaptive Hsearch&Lsearch
问题即求所有满足二维偏序的二元组的权值
仿照平面最近点对的
考虑取若干阈值
只考虑
所以只要在加入
具体常数大概是
#include <bits/stdc++.h>
using namespace std;
const int dx[] = {-1, -1, -1, 0, 0, 0, 1, 1, 1}, dy[] = {-1, 0, 1, -1, 0, 1, -1, 0, 1}, mod = 1 << 20, M = mod - 1;
struct node {
long long x, y;
}a[250005];
int n, m, cnt;
long long ans[250005];
vector<int> v[250005];
vector<node> b[250005], q[250005];
struct Htable {
pair<long long, int> a[mod];
auto &operator [] (long long x) {
for(uint p = x * 10815553818077224714ull >> 44;; ++p &= M)
if(!a[p].first || a[p].first == x)
return a[p];
}
void clear() {
return fill(a, a + mod, make_pair(0, 0));
}
}mp;
long long f(long long x) {
return x * x;
}
long long dis(node a, node b) {
return f(a.x - b.x) + f(a.y - b.y);
}
struct BIT {
long long t[250005];
BIT() {
memset(t, 0x3f, sizeof(t));
}
int lowbit(int x) {
return x & -x;
}
void update(int x, long long v) {
while(x)
t[x] = min(t[x], v), x -= lowbit(x);
return;
}
long long query(int x) {
long long s = 1e18;
while(x <= n)
s = min(s, t[x]), x += lowbit(x);
return s;
}
}T;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i++)
cin >> a[i].x >> a[i].y;
for(int i = 1, l, r; i <= m; i++)
cin >> l >> r, q[r].push_back({l, i});
for(int k = 1; k < 27; k++) {
cnt = 0, mp.clear();
for(int i = 1; i <= n; i++) {
int x = a[i].x >> k, y = a[i].y >> k;
x++, y++;
for(int l = 0; l < 9; l++) {
int nx = x + dx[l], ny = y + dy[l];
auto &t = mp[nx * (1ll << 27) | ny];
if(t.first) {
vector<int> tmp;
for(int j : v[t.second]) {
auto d = dis(a[i], a[j]);
b[i].push_back({j, d});
if(d >= (1ll << (k - 1 << 1)))
tmp.push_back(j);
}
v[t.second] = tmp;
}
}
auto &t = mp[{x * (1ll << 27) | y}];
if(!t.first)
t.second = ++cnt;
t.first = x * (1ll << 27) | y, v[t.second].push_back(i);
}
for(int i = 1; i <= cnt; i++)
v[i].clear();
}
for(int i = 1; i <= n; i++) {
for(auto j : b[i])
T.update(j.x, j.y);
for(auto j : q[i])
ans[j.y] = T.query(j.x);
}
for(int i = 1; i <= m; i++)
cout << ans[i] << '\n';
return 0;
}