• bzoj 1288: Neighbours


    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
    ",a0,a1,a2,a3,a4);
        return 0;
    }
  • 相关阅读:
    Redis 缓存 + Spring 的集成示例
    ETCD相关介绍--整体概念及原理方面
    SpringCloud微框架系列整体模块梳理
    win7如何修改磁盘驱动器号,怎么修改磁盘名称
    Android ListView中子控件的状态保存以及点击子控件改变子控件状态
    Android 自己动手写ListView学习其原理 3 ItemClick,ItemLongClick,View复用
    点击itemView选中checkbox
    Android-RecyclerView-Item点击事件设置
    onItemClickListener监听的整个item的点击。如何只监听那个framelayout的点击 onItemClickListener监听的整个item的点击。如何只监听那个framelayout的点击
    listView中setOnItemClickListener和getSelectedItemPosition()取不到position问题
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7122586.html
Copyright © 2020-2023  润新知