• [补题]2017多校5A/HDU6085-Rikka with Candies-bitset优化


    2017多校5-A/bitset优化

    http://acm.hdu.edu.cn/showproblem.php?pid=6085

    题意:给序列(A[1,dots,n])(B[1,dots,m]),q次询问每次给一个(dleq max B_i),问有多少对((i,j):A_imod B_i=d),答案对2取模,(n,m,qleq 5 imes 10^4)

    一开始读错题意以为右边也是取模

    看题解会的,思路来自于注意到(Amod B=d (d<B)iff exist kin N:A=kb+d),也就是(A-d=kb),不管是左边的形式,还是对2取模,大概都需要能够想到尝试bitset的优化,用bitset存一个A和B,如果是暴力的话就直接是:

    rep(i,1,m){
        scanf("%d",&B[i]);
        for(int j=0;j<=N-5;j+=B[i])b[i].set(j);
    }
    rep(i,1,q){
        int d;scanf("%d",&d);
        int ret=0;
        rep(j,1,m)if(d<B[j])ret^=(((a>>d)&b[j]).count())&1;
        printf("%d
    ",ret);
    }
    

    这样做是个大暴力,我好像出不了奇迹,那就优化呗,暴力的瓶颈在于每次都要对每一个询问(d)都要遍历每一个(b),一个个取and,于是其实我们就考虑这(m)个b的bitset的信息能不能合并起来?

    对某个位置(k),合并之后的(B[k]=oplus_{i=1}^m B[i][k])的结果(以为是要奇偶性,相加相当于异或),而又要保证(d<B),那我们就是从大到小枚举(B)啦~

    rep(i,1,m){
        int x;scanf("%d",&x);
        mx=max(mx,x);b.set(x);
    }
    for(int i=mx;i>=0;i--){
        ret[i]=((a>>i)&B).count()&1;
        if(b[i])
            for(int k=0;k<=N-5;k+=i)B[k]=B[k]^1;
    }
    
  • 相关阅读:
    MVC 中301永久重定向
    String
    redis key设置过期时间
    hbase java 增加列族
    hbase 物理存储
    java 类图
    SSH hql中文查询时乱码快速解决
    json和pickle的序列化与反序列化
    python之生成器与迭代器
    安装traits库心得
  • 原文地址:https://www.cnblogs.com/yoshinow2001/p/14651002.html
Copyright © 2020-2023  润新知