Description
很久以前, 有一个小小的国度, 为了方便, 我们可以把它想象为一个大大的矩形, 矩形的左下角为(0, 0), 右上角为(w, h), 共有(w + 1) * (h + 1)个整点, 在本题中我们只考虑所有的整点.在这个国度里, 有n座山峰, 第i座位于整点(xi, yi)上, 现在我们需要选择一些整点来修建房子, 除了n座山峰以外还有(w + 1) * (h + 1) – n个可以修建房子的地方. 有些点修建房子风景会更加优美, 比如从这个点往北眺望可以看到一座山峰即你位于(x, y), 而存在一座位于(x, y + d)的山峰, 这样你就可以欣赏到山峰的美景, 东, 西, 南三个方向也同样如此.如果某个点上某个方向可以眺望到某座山峰, 那么我们称这座山峰为这个点的一个neighbour, 当然neighbour越多, 这个点修建房子风景会越优美.作为房地产开发公司的技术人员, 你的任务很简单, 统计在(w + 1) * (h + 1) – n 个点中neighbours总数为0, 1, 2, 3, 4的点的总数分别为多少
Input
输入文件第一行为3个正整数, w, h, n. 以下n行,每行有两个整数(xi, yi), 表示第i个山峰的位置(0 <= xi <= w, 0 <= yi <= h).
Output
输出文件有5个数, 分别为neighbours总数为0, 1, 2, 3, 4的点的个数.
离散化后用排序+树状数组统计一下
#include<bits/stdc++.h> typedef long long i64; const int N=5e5+111; char buf[100001],*ptr=buf+100000; int G(){ if(ptr-buf==100000)fread(ptr=buf,1,100000,stdin); return *ptr++; } int _(){ int x=0; if(ptr-buf<99900){ while(*ptr<48)++ptr; while(*ptr>47)x=x*10+*ptr++-48; }else{ int c=G(); while(c<48)c=G(); while(c>47)x=x*10+c-48,c=G(); } return x; } i64 a0,a1,a2,a3,a4; int xm,ym,n; int xs[N],ys[N],xp,yp; int xw[N][2],yw[N][2],f[N],g[N]; struct pos{ int x,y; }ps[N],ps2[N],qs[N],qs2[N]; bool cmpx(pos a,pos b){ return a.x<b.x||a.x==b.x&&a.y<b.y; } bool cmpy(pos a,pos b){ return a.y<b.y||a.y==b.y&&a.x<b.x; } void inc(int*f,int w){ for(++w;w<=n;w+=w&-w)++f[w]; } int sum(int*f,int w){ int s=0; for(++w;w;w-=w&-w)s+=f[w]; return s; } int main(){ xm=_()+1,ym=_()+1,n=_(); for(int i=0;i<n;++i){ ps[i].x=xs[i]=_(); ps[i].y=ys[i]=_(); } std::sort(xs,xs+n); xp=std::unique(xs,xs+n)-xs; std::sort(ys,ys+n); yp=std::unique(ys,ys+n)-ys; a0=i64(xm-xp)*(ym-yp); for(int i=0;i<n;++i){ ps[i].x=std::lower_bound(xs,xs+xp,ps[i].x)-xs; ps[i].y=std::lower_bound(ys,ys+yp,ps[i].y)-ys; } memcpy(ps2,ps,n*sizeof(pos)); std::sort(ps,ps+n,cmpx); for(int i=0,j=0,p1,p2;i<n;i=j){ int x=ps[i].x; for(++j;j<n&&ps[j].x==x;++j){ p1=ps[j-1].y,p2=ps[j].y; a2+=ys[p2]-ys[p1]-(p2-p1); } p1=yw[x][0]=ps[i].y; p2=yw[x][1]=ps[j-1].y; a1+=ys[p1]+ym-ys[p2]-(p1+yp-p2); } std::sort(ps2,ps2+n,cmpy); for(int i=0,j=0,p1,p2;i<n;i=j){ int y=ps2[i].y; for(++j;j<n&&ps2[j].y==y;++j){ p1=ps2[j-1].x,p2=ps2[j].x; a2+=xs[p2]-xs[p1]-(p2-p1); } p1=ps2[i].x; p2=ps2[j-1].x; a1+=xs[p1]+xm-xs[p2]-(p1+xp-p2); qs[y]=(pos){p1,y}; qs2[y]=(pos){p2,y}; } std::sort(qs,qs+yp,cmpx); std::sort(qs2,qs2+yp,cmpx); for(int x=0,p=0,pp=0,i=0;x<xp;++x){ for(;p<yp&&qs2[p].x<x;++p)inc(f,qs2[p].y); for(;pp<yp&&qs[pp].x<x;++pp)inc(g,qs[pp].y); for(++i;i<n&&ps[i].x==x;++i){ int p1=ps[i-1].y,p2=ps[i].y; a4+=sum(g,p2-1)-sum(f,p2-1)-(sum(g,p1)-sum(f,p1)); } a2+=sum(f,yw[x][0]-1)+p-sum(f,yw[x][1]); } memset(f,0,sizeof(int)*(n+2)); for(int x=xp-1,p=yp-1,t=0;x>=0;--x){ for(;p>=0&&qs[p].x>x;--p)inc(f,qs[p].y),++t; int s0,s1; a2+=(s0=sum(f,yw[x][0]-1))+t-(s1=sum(f,yw[x][1])); } a3=i64(xm)*ym-n-a0-a1-a2-a4; printf("%lld %lld %lld %lld %lld\n",a0,a1,a2,a3,a4); return 0; }