洛谷 P2906 [USACO08OPEN]牛的街区Cow Neighborhoods | Set+并查集
题目:
https://www.luogu.org/problemnew/show/P2906
题解:
垃圾水题
#include<cstdio> #include<algorithm> #include<set> #define N 100005 typedef long long ll; using namespace std; struct node { ll x,y,id; bool operator < (const node &a)const {return y<a.y || (y==a.y && id<a.id);} }p[N]; multiset <node> s; multiset <node> :: iterator it; ll n,c,q[N],l,r=-1,fa[N],sz[N],ans,mx; bool cmp(node a,node b) {return a.x<b.x || (a.x==b.x && a.y<b.y);} ll find(ll x) {return fa[x]=fa[x]==x?x:find(fa[x]);} void merge(ll i,ll j) { ll x=find(i),y=find(j); if (x==y) return; if (sz[x]>sz[y]) swap(x,y); fa[x]=y,sz[y]+=sz[x]; } int main() { scanf("%lld%lld",&n,&c); for (ll i=1,x,y;i<=n;i++) scanf("%lld%lld",&x,&y),p[i].x=x+y,p[i].y=x-y,p[i].id=fa[i]=i,sz[i]=1; sort(p+1,p+1+n,cmp); for (ll i=1;i<=n;i++) { q[++r]=i; while (l<r && p[q[r]].x-p[q[l]].x>c) s.erase(p[q[l]]),l++; it=s.insert(p[i]); if (it!=s.begin()) if ((p[i].y-(*(--it)).y<=c)) merge(p[i].id,((*it).id)),it++; else it++; if (++it!=s.end() && (*(it)).y-p[i].y<=c ) merge(p[i].id,(*it).id); } for (ll i=1;i<=n;i++) if (find(i)==i) ans++,mx=max(mx,sz[i]); printf("%lld %lld\n",ans,mx); return 0; }