【bzoj1604】: [Usaco2008 Open]Cow Neighborhoods 奶牛的鄰居
阿新 • • 發佈:2019-02-10
先是曼哈頓距離的變換
一維排序 另一維用splay維護前驅和後繼 判斷一下距離是否小於c 如果小於並查集並起來 就行了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
const int N=210011;
const int inf=0x3f3f3f3f;
struct node{int x,y;}a[N];
struct Node{int l,r,fa,d;}sp[N];
int fa[N],size[N],root,cnt,vis[N];
int n,c;
int cmp(node x,node y)
{
if(x.x==y.x)return x.y<y.y;
return x.x<y.x;
}
int Find(int x)
{
if(x==fa[x])return x;
return fa[x]=Find(fa[x]);
}
void merge(int x,int y)
{
x=Find(x);
y=Find(y);
if(x==y)return;
if(size[y]<size[x])swap(x,y);
size[y]+=size[x];
fa[x]=y;
}
void zig(int x)
{
int y=sp[x].fa;
sp[y].l=sp[x].r;
if(sp[x].r)sp[sp[x].r].fa=y;
sp[x].fa=sp[y].fa;
if(sp[y].fa)
if(sp[sp[y].fa].l==y)sp[sp[y].fa].l=x;
else sp[sp[y].fa].r=x;
sp[x].r=y,sp[y].fa=x;
}
void zag(int x)
{
int y=sp[x].fa;
sp[y].r=sp[x].l;
if(sp[x].l)sp[sp[x].l].fa=y;
sp[x].fa=sp[y].fa;
if (sp[y].fa)
if(sp[sp[y].fa].l==y)sp[sp[y].fa].l=x;
else sp[sp[y].fa].r=x;
sp[x].l=y,sp[y].fa=x;
}
void splay(int x,int aim)
{
while(sp[x].fa!=aim)
{
//cout<<x<<" "<<aim<<endl;
int y=sp[x].fa;
if(sp[y].fa==aim)
{
if(sp[y].l==x)zig(x);
else zag(x);
}
else
{
if(sp[sp[y].fa].l==y)
{
if(sp[y].l==x)zig(y),zig(x);
else zag(x),zig(x);
}
else
{
if(sp[y].r==x)zag(y),zag(x);
else zig(x),zag(x);
}
}
}
if(aim==0)root=x;
}
int find(int x,int d,int ret)//返回小於等於d的數
{
if(x==0)return ret;
if(sp[x].d>d)return find(sp[x].l,d,ret);
return find(sp[x].r,d,x);
}
int getnext(int x)
{
x=sp[x].r;
while(sp[x].l)x=sp[x].l;
return x;
}
int getlast(int x)
{
x=sp[x].l;
while(sp[x].r)x=sp[x].r;
return x;
}
void insert(int d,int xx)
{
int x=find(root,d-1,0);
splay(x,0);
int y=getnext(x);
// cout<<y<<" "<<x<<endl;
splay(y,x);//cout<<"0.0";
sp[y].l=xx;
sp[xx].fa=y;
sp[xx].d=d;
if(sp[xx].d-sp[x].d<=c&&sp[x].d!=-inf)merge(xx,x);
if(sp[y].d-sp[xx].d<=c&&sp[x].d!=inf)merge(xx,y);
}
void del(int x)
{
splay(x,0);
int xx=getlast(x);
splay(xx,0);
int y=getnext(x);
//cout<<xx<<" "<<y<<endl;
splay(y,xx);
sp[y].l=0;
}
void bili()
{
cnt=2;
sp[n+1].d=inf;
sp[2+n].d=-inf;
sp[1+n].l=2+n;
sp[2+n].fa=1+n;
root=1+n;
}
void debug(int x)
{
if(!x)return;
debug(sp[x].l);
cout<<x<<" ";
debug(sp[x].r);
}
int main()
{
cin>>n>>c;
for(int i=1;i<=n;i++)
{
int X,Y;
scanf("%d%d",&X,&Y);
a[i].x=X+Y,a[i].y=X-Y;
}
for(int i=1;i<=n;i++)fa[i]=i,size[i]=1;
sort(a+1,a+1+n,cmp);
bili();
int l=1;
for(int i=1;i<=n;i++)
{
while(l<=i&&a[i].x-a[l].x>c)del(l),l++;
insert(a[i].y,i);
//cout<<l<<" "<<i<<endl;
//cout<<root<<endl;
//debug(root);
//cout<<endl;
}
int ans=0;
int gs=0;
for(int i=1;i<=n;i++)
{
int x=Find(i);
if(vis[x]==0)vis[x]=1,gs++;
ans=max(ans,size[x]);
}
printf("%d %d",gs,ans);
}