• CH Round #46A 磁力块


    还是一道好题的

    对于一个磁石是否被吸引,有两个关键字:距离和质量。(二维偏序??)

    好像是很厉害的分块姿势,先按第一关键字排序,在块中按第二关键字排

    进行bfs,对于当前磁石,有1~k-1个块是第一关键字全部小于等于当前磁石的,那么暴力从块首往后,找到第一个第二关键字大于当前磁石属性的,那么前面都捡走,以后可以从这里开始找。

    暴力枚举第k个块找答案。

    一个优化就是找k的时候直接比较当前块的最大值就行了,因为当前的属性肯定是>kmin,<kmax滴

    (垃圾CH本机AC提交WA幸好最后我搞对了)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    
    int n;
    struct node{LL dis,m,p,r;}a[310000];bool v[310000];
    bool cmp1(node n1,node n2){return n1.m<n2.m;}
    bool cmp2(node n1,node n2){return n1.dis<n2.dis;}
    
    int block,st[310000];
    struct LIST
    {
        LL p,r;
    }list[310000];
    int be[610];LL mx[610];
    
    int findk(LL p)
    {
        for(int i=1;i<=block;i++)
            if(p<mx[i])return i;
        return block+1;
    }
    
    int main()
    {
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
        
        LL xx,yy,x,y;
        scanf("%lld%lld%lld%lld%d",&xx,&yy,&list[1].p,&list[1].r,&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld%lld%lld%lld",&x,&y,&a[i].m,&a[i].p,&a[i].r);
            a[i].dis=(x-xx)*(x-xx)+(y-yy)*(y-yy);
        }
        sort(a+1,a+n+1,cmp1);
        
        block=(int(sqrt(double(n+1))))+1;
        for(int i=1;i<=n;i++)st[i]=(i-1)/block+1;
        for(int i=1;i<=block;i++)
        {
            int St=(i-1)*block+1,Ed=min(i*block,n);mx[i]=a[Ed].m;
            if(St<=Ed)sort(a+St,a+Ed+1,cmp2);
        }
        
        for(int i=1;i<=block;i++)be[i]=1;
        memset(v,false,sizeof(v));
        int head=1,tail=2,ans=0;
        while(head<tail)
        {
            LL p=list[head].p,r=list[head].r;
            int k=findk(p);
            for(int i=1;i<=k-1;i++)
            {
                for(int j=be[i];j<=block&&(i-1)*block+j<=n;j++)
                {
                    int u=(i-1)*block+j;
                    if(a[u].dis>r*r){be[i]=j;break;}
                    {
                        if(v[u]==false)
                        {
                            v[u]=true;
                            ans++;
                            list[tail].p=a[u].p, list[tail].r=a[u].r;
                            tail++;
                        }
                    }
                }
            }
            if(k!=block+1)
            {
                for(int j=be[k];j<=block&&(k-1)*block+j<=n;j++)
                {
                    int u=(k-1)*block+j;
                    if(a[u].dis>r*r)break;
                    else if(a[u].m<=p)
                    {
                        if(v[u]==false)
                        {
                            v[u]=true;
                            ans++;
                            list[tail].p=a[u].p, list[tail].r=a[u].r;
                            tail++;
                        }
                    }
                }
            }
            head++;
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Keras & Theano 输出中间层结果
    keras & tensorflow 列出可用GPU 和 切换CPU & GPU
    Visualizing CNN Layer in Keras
    [python]使用django快速生成自己的博客小站,含详细部署方法
    [JetBrains注册] 利用教育邮箱注册JetBrains产品(pycharm、idea等)的方法
    【python】pycharm常用配置快速入门。
    一道笔试题来理顺Java中的值传递和引用传递
    集群扩容的常规解决:一致性hash算法
    [面经]春季跳槽面筋总结 [2018年3月17]
    TestNG的简单使用
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9432686.html
Copyright © 2020-2023  润新知