ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

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;
}

 

posted on 2017-07-05 17:35  nul  阅读(125)  评论(0编辑  收藏  举报