# 【BZOJ】1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居

【算法】并查集+平衡树+数学+扫描线

【题解】

X1=x1+y1,Y1=x1-y1，则转化为

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<set>
using namespace std;
const int maxn=100010;
struct cyc{
int y,d;
bool operator < (const cyc &a)const{
return y<a.y||(y==a.y&&d<a.d);
}
};
struct node{int x,y;}a[maxn];
set<cyc>s;
set<cyc>::iterator it;
int fa[maxn],n,c,b[maxn];
char c;int s=0,t=1;
while(!isdigit(c=getchar()))if(c=='-')t=-1;
do{s=s*10+c-'0';}while(isdigit(c=getchar()));
return s*t;
}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
bool cmp(node a,node b){return a.x<b.x;}
int main(){
for(int i=1;i<=n;i++){
a[i]=(node){a[i].x+a[i].y,a[i].x-a[i].y};
}
sort(a+1,a+n+1,cmp);
int l=1;
s.insert((cyc){a[1].y,1});
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=2;i<=n;i++){//一边往前，一边两端
while(a[i].x-a[l].x>c)s.erase((cyc){a[l].y,l}),l++;
it=s.lower_bound((cyc){a[i].y,i});
if(it!=s.end()&&it->y-a[i].y<=c&&find(i)!=find(it->d))fa[fa[i]]=fa[it->d];
if(it!=s.begin()&&a[i].y-(--it)->y<=c&&find(i)!=find(it->d))fa[fa[i]]=fa[it->d];
s.insert((cyc){a[i].y,i});
}
int mx=0,num=0;
for(int i=1;i<=n;i++)b[find(i)]++;
for(int i=1;i<=n;i++)if(b[i]){
num++;
if(b[i]>mx)mx=b[i];
}
printf("%d %d",num,mx);
return 0;
}
View Code

posted @ 2017-09-15 17:04  ONION_CYC  阅读(218)  评论(0编辑  收藏  举报