bzoj1604 / P2906 [USACO08OPEN]牛的街区Cow Neighborhoods
P2906 [USACO08OPEN]牛的街区Cow Neighborhoods
考虑维护曼哈顿距离:$\left | x_{1}-x_{2} \right |+\left | y_{1}-y_{2} \right |$
看起来很难维护的样子,我们尝试转化
设两个点$(x_{1},y_{1}),(x_{2},y_{2}) (x_{1}>=x_{2})$
那么它们的曼哈顿距离有2种情况
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})$
于是我们就可以转为维护$(X=x+y,Y=x-y)$
这样曼哈顿距离就愉快地转化为$max(X_{1}-X_{2},Y_{1}-Y_{2})$了
我们先把所有坐标按$x$升序排一遍。
蓝后$x$坐标用一个队列维护
$y$坐标则用$multiset$维护(当然你愿意的话也可以打个平衡树(逃))
每次在$multiset$里搞搞啥$lower\_bound$操作就行了。
至于点的联通问题,搞一个并查集
end.
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<set> #define re register using namespace std; typedef long long ll; void read(ll &x){ 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(){ scanf("%d",&n); read(c); t=n; ll q1,q2; for(re int i=1;i<=n;++i){ read(q1); read(q2); 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; }