# bzoj1604 / P2906 [USACO08OPEN]牛的街区Cow Neighborhoods

P2906 [USACO08OPEN]牛的街区Cow Neighborhoods

1.$y_{1}>y_{2}:\left | x_{1}-x_{2} \right |+\left | y_{1}-y_{2} \right |=x_{1}-x_{2}+y_{1}-y_{2}=(x_{1}+y_{1})-(x_{2}+y_{2})$

2.$y_{1}<y_{2}:\left | x_{1}-x_{2} \right |+\left | y_{1}-y_{2} \right |=x_{1}-x_{2}-y_{1}+y_{2}=(x_{1}-y_{1})-(x_{2}-y_{2})$

$y$坐标则用$multiset$维护（当然你愿意的话也可以打个平衡树（逃））

end.

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<set>
#define re register
using namespace std;
typedef long long ll;
char c=getchar();x=0;
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
}
int max(int &a,int &b){return a>b?a:b;}
#define N 100002
struct data{
ll x,y;int id;
data(){}
data(ll A,ll B,int C):
x(A),y(B),id(C)
{}
bool operator < (const data &tmp) const{return y<tmp.y;}
}a[N];
bool cmp(const data &A,const data &B){return A.x<B.x;}
multiset <data> s;
int n,t,mxd=-1e9,fa[N],siz[N]; ll c;
int found(int x){return fa[x]==x?x:fa[x]=found(fa[x]);}
void uni(int x,int y){
int r1=found(x),r2=found(y);
if(r1!=r2){
siz[r1]+=siz[r2]; --t;
siz[r2]=0; fa[r2]=r1;
}
}
int main(){
for(re int i=1;i<=n;++i){
fa[i]=i; siz[i]=1;
a[i]=data(q1+q2,q1-q2,i);
}sort(a+1,a+n+1,cmp);
s.insert(data(0,1e16,0));
s.insert(data(0,-1e16,0));//添加边界防止指针越界
s.insert(a[1]); int hd=1;
multiset<data>::iterator it;
for(re int i=2;i<=n;++i){
while(a[hd].x+c<a[i].x) s.erase(s.find(a[hd++]));//队列维护
it=s.lower_bound(a[i]);//找到第一个>=a[i].y的
if((*it).y-a[i].y<=c) uni((*it).id,a[i].id);
if(a[i].y-(*(--it)).y<=c) uni((*it).id,a[i].id);
s.insert(a[i]);
}printf("%d ",t);
for(re int i=1;i<=n;++i) mxd=max(mxd,siz[i]);
printf("%d",mxd);
return 0;
}

posted @ 2018-10-25 22:10  kafuuchino  阅读(124)  评论(0编辑  收藏  举报