1. 程式人生 > >【bzoj1604】: [Usaco2008 Open]Cow Neighborhoods 奶牛的鄰居

【bzoj1604】: [Usaco2008 Open]Cow Neighborhoods 奶牛的鄰居

先是曼哈頓距離的變換
一維排序 另一維用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); }