题解:P12506 「ROI 2025 Day2」沼泽里的青蛙
考虑将平面
- 块内所有点相互有边。
- 一个点最多和其周围
5\times 5 个块的点连边。
设点数
可以发现不考虑重块点和重块点连边后,剩余边总量是
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i = (a);i <= (b);++i)
using ll = long long;
const int N = 1e5 + 5;
int n,B,ans[N],fa[N * 2];
ll m,X[N],Y[N];
map<pair<int,int>,vector<int>> P;
int fnd(int x){ return x == fa[x] ? x : fa[x] = fnd(fa[x]); }
int main(){
scanf("%d%lld",&n,&m),B = (m + 1) / 2,iota(fa,fa + N * 2,0);
rep(i,1,n) scanf("%lld%lld",X + i,Y + i),P[make_pair(X[i] / B,Y[i] / B)].push_back(i);
for(auto&[I,V] : P)
if(V.size() > 2) for(int k : V) fa[fnd(k)] = fnd(k + n);
else
rep(x,I.first - 2,I.first + 2)
rep(y,I.second - 2,I.second + 2)
if(P.count(make_pair(x,y)))
for(int p : V)
for(int q : P[make_pair(x,y)])
if(p != q && (X[p] - X[q]) * (X[p] - X[q]) + (Y[p] - Y[q]) * (Y[p] - Y[q]) <= m * m)
fa[fnd(p)] = fnd(q + n),fa[fnd(q)] = fnd(p + n);
rep(i,1,n) putchar((fnd(i) == fnd(i + n)) + '0');
return 0;
}