zoukankan      html  css  js  c++  java
  • HDU 6085 Rikka with Candies(bitset)

    【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=6085

    【题目大意】

      给出一个数组a一个数组b,以及询问数组c,
      问对于每个c有多少对a%b=c,答案对2取模

    【题解】

      考虑对2取模我们发现答案等价于数字的xor,01状态可以用bitset保存,
      在bitset上存a的权值数组,那么每次只要将b*i~b*(i+1)-1的数值xor到答案数组的0~b-1上去即可,
      鉴于bitset没有截取区间的功能,我们手写压位,
      考虑压32位之后不是32倍数的部分截取起来非常尴尬,
      因此我们保存其偏移量为0~31的数组,这样取区间就比较方便了。

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int N=10010;
    struct Bitset{
        unsigned int u[N];
        void reset(){memset(u,0,sizeof(u));}
        void set(int x){u[x>>5]|=1<<(x&31);}
        void flip(int x){u[x>>5]^=1<<(x&31);}
        bool test(int x){return u[x>>5]&(1<<(x&31));}
        void reset(int x){if(test(x))flip(x);}
    }a[32],ans;
    void Solve(int l,int r){
        while((r-l)&31){r--;if(a[0].test(r))ans.flip(r-l);}
        int m=0; while(l&31)l++,r++,m++;
        l>>=5; r>>=5;
        for(int i=l;i<r;i++)ans.u[i-l]^=a[m].u[i];
    }
    int T,n,m,q,x,mx;
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d%d%d",&n,&m,&q);
            for(int i=0;i<32;i++)a[i].reset(); 
            ans.reset(); mx=0;
            for(int i=1;i<=n;i++){
                scanf("%d",&x); mx=max(x,mx);
                for(int j=0;j<32;j++)a[j].set(x+j);
            }
            for(int i=1;i<=m;i++){
                scanf("%d",&x);
                for(int j=0;j<=mx;j+=x)Solve(j,min(mx+1,j+x));
            }
            while(q--){
                scanf("%d",&x);
                if(ans.test(x))puts("1");
                else puts("0");
            }
        }return 0;
    }
  • 相关阅读:
    hdu2151
    hdu1028
    hdu1398
    hdu1465
    hdu2853
    poj2195
    poj2255
    JS正则校验数字,特殊字符,邮箱基本格式
    JS正则校验数字,特殊字符,邮箱基本格式
    io读取文件内容乱码处理
  • 原文地址:https://www.cnblogs.com/forever97/p/hdu6085.html
Copyright © 2011-2022 走看看