zoukankan      html  css  js  c++  java
  • bzoj1807: [Ioi2007]Pairs 彼此能听得见的动物对数

    很有趣的一道题233

    一维送分的,排序后弄个指针扫描维护当前最远能够听见的位置即可

    二维我会肝两次分治,后来看claris博客发现可以把曼哈顿距离换成切比雪夫距离,要满足|xi-xj|<=D&&|yi-yj|<=D

    这样就好做了,转化成区间问题扫描线+线段树水

    三维不管高,然后同样的转换,因为m很小对于每个动物都可以枚举去第几层,用二维前缀和出解即可

    然而卡空间卡空间边界超久。。。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    
    #define mp(k,i,j) mp[k][i][j+105]
    using namespace std;
    typedef long long LL;
    
    int n,D,m,c[110000];
    void solve1()
    {
        scanf("%d%d%d",&n,&D,&m);
        for(int i=1;i<=n;i++)scanf("%d",&c[i]);
        sort(c+1,c+n+1);
        int r=0;LL ans=0;
        for(int l=1;l<=n;l++)
        {
            while(r<n&&c[r+1]-c[l]<=D)r++;
            ans+=r-l;
        }
        printf("%lld
    ",ans);
    }
    
    //--------------------------------------------------------------------------------
    
    int s[210000];
    int lowbit(int x){return x&-x;}
    void change(int x,int k)
    {
        while(x<=n)
        {
            s[x]+=k;
            x+=lowbit(x);
        }
    }
    int getsum(int x)
    {
        int ret=0;
        while(x>0)
        {
            ret+=s[x];
            x-=lowbit(x);
        }
        return ret;
    }
    struct node2{int x,y;}p[110000];                        int lslen,ls[110000];
    bool node2_cmp(node2 n1,node2 n2){return n1.x<n2.x;}    int LB(int x){return lower_bound(ls+1,ls+lslen+1,x)-ls;}
                                                            int UB(int x){return upper_bound(ls+1,ls+lslen+1,x)-ls;}
    struct line
    {
        int op,x,y;
        line(){}
        line(int OP,int X,int Y){op=OP;x=X;y=Y;}
    }li[310000];int lilen;
    bool line_cmp(line l1,line l2){return l1.x==l2.x?l1.op<l2.op:l1.x<l2.x;}
    void solve2()
    {
        scanf("%d%d%d",&n,&D,&m);lilen=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&p[i].x,&p[i].y),p[i].x*=2,p[i].y*=2;
            int xx=(p[i].x+p[i].y)/2,yy=(p[i].x-p[i].y)/2;
            p[i].x=xx,p[i].y=yy;
            ls[++lslen]=yy;
            
            li[++lilen]=line(0,p[i].x-D,p[i].y);
            li[++lilen]=line(1,p[i].x,p[i].y);
            li[++lilen]=line(2,p[i].x+D,p[i].y);
        }
        sort(ls+1,ls+lslen+1);
        lslen=unique(ls+1,ls+lslen+1)-ls-1;
        sort(li+1,li+lilen+1,line_cmp);
        
        LL ans=0;
        memset(s,0,sizeof(s));
        for(int i=1;i<=lilen;i++)
        {
            if(li[i].op==0)change(LB(li[i].y),1);
            else if(li[i].op==1)ans+=getsum(UB(li[i].y+D)-1)-getsum(LB(li[i].y-D)-1)-1;
            else change(LB(li[i].y),-1);
        }
        printf("%lld
    ",ans/2);
    }
    
    //--------------------------------------------------------------------------------
    
    struct node3{int x,y,z;}o[210000];
    int mp[80][210][210];
    void solve3()
    {
        int x,y,z;
        scanf("%d%d%d",&n,&D,&m);
        memset(mp,0,sizeof(mp));
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d",&o[i].x,&o[i].y,&o[i].z),o[i].x*=2,o[i].y*=2;
            int xx=(o[i].x+o[i].y)/2,yy=(o[i].x-o[i].y)/2;
            o[i].x=xx,o[i].y=yy;
            mp(o[i].z,o[i].x,o[i].y)++;
        }
        for(int k=1;k<=m;k++)
            for(int i=1;i<=200;i++)
                for(int j=-100;j<=100;j++)
                    mp(k,i,j)+=mp(k,i-1,j)+mp(k,i,j-1)-mp(k,i-1,j-1);
        LL ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int k=1;k<=m;k++)
            {
                int W=D-abs(o[i].z-k);if(W<0)continue;
                ans+=mp(k,min(200,o[i].x+W),min(100,o[i].y+W))
                    -mp(k,min(200,o[i].x+W),max(-100,o[i].y-W-1))
                    -mp(k,max(0,o[i].x-W-1),min(100,o[i].y+W))
                    +mp(k,max(0,o[i].x-W-1),max(-100,o[i].y-W-1));
            }
            ans--;
        }
        printf("%lld
    ",ans/2);
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int B;
        scanf("%d",&B);
        if(B==1)solve1();
        else if(B==2)solve2();
        else solve3();
        return 0;
    }
  • 相关阅读:
    函数式对象
    PageRank网页排名算法
    文档倒排序索引
    单词共现算法
    MapReduce关系代数运算
    矩阵乘法的MapReduce实现
    对象序列化(二)
    信息流产品和内容推荐算法
    从企业实操的角度谈深度学习(图像方向)的底层逻辑之概念普及
    Python深度学习企业实战之TensorFlow的底层原理及安装
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9849158.html
Copyright © 2011-2022 走看看