hdu 6085 (bitset)

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <bitset>

using namespace std;
bitset<50000+10>a,b,ans,t;
/**
 * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6085
 * 题目意思:给定A,B两个数组,分别n,m;个元素,q次查询,每次询问,A%B==k有多少对数?答案mod2再输出。
 * 思路:如题解所说bitset大法,先说明bitset位标记。reset() 表示清空为0,
 * set(i)表示将第i为二进制设为1,flip(i),将第i位取反,count()统计二进制位1的个数
 *  那么原问题,是 (A-k)%B==0 的个数。我们可以从B数组中的最大值进行枚举。位标记出现的,k>=max的一定为0;
 * 当枚举到ans[i]时,B数组中大于等于i的元素都会为ans[i]贡献答案,所以我用t数组表示:B数组中大于等于i的元素的倍数;
 * 所以ans[i]=(t&(a>>i))二进制1的个数;
 */
int main()
{
    int ncase;
    scanf("%d",&ncase);
    while(ncase--)
    {
        int n,m,q,x,mx=0;
        a.reset(),b.reset(),ans.reset(),t.reset();
        scanf("%d%d%d",&n,&m,&q);
        for(int i=0;i<n;i++) scanf("%d",&x),a.set(x);
        for(int i=0;i<m;i++) scanf("%d",&x),b.set(x),mx=max(mx,x);
        for(int i=mx;i>=0;i--)
        {
            ans[i]=(t&(a>>i)).count()&1;
            if(b[i]) for(int j=0;j<=50000;j+=i) t.flip(j);
        }
        while(q--)
        {
            scanf("%d",&x);
            printf("%d\n",ans[x]?1:0);
        }
    }
    return 0;
}
posted @ 2017-08-12 09:58  Code-dream  阅读(168)  评论(0编辑  收藏  举报