bitset(hdu 6085)

来源:互联网 发布:sqlserver 2008 64 编辑:程序博客网 时间:2024/05/20 07:20

题意:给定两个数组a和b然后q次询问,输出ai%bi==k的个数的奇偶性。
思路:可以转化为给a数组每个都减去k求(ai-k)%bi==0的有多少个,又因为只有当bi>k时才会有结果所以可以预处理处所有的答案为k的结果最后O(1)输出就好了。枚举k然后从大到小枚举bi每次都将bi的倍数统计出来
然后每次就可以算出(ai-k)%bi==0的有多少个了,具体的看代码和注释。
这里有一个关于bitset的用法及函数

#include<cstdio>#include<cstring>#include<bitset>#include<iostream>#include<algorithm>#define LL long longusing namespace std;const int maxn=1e6+10;bitset<50010> a,b,ans,bx;void solve(int tmp){    for(int i=tmp;i>=0;i--)//枚举k    {        ans[i]=(bx&(a>>i)).count()&1;        /*        ans[i]存的是a[j]%b[j]==i的有多少个的奇偶性        bx[i]里面是i%b[j]==0的奇偶性        a>>i相当于将所有的ai的值都减了i丢掉了<0的值        &1是判断奇偶性的        判断的是(ai-k)%bj==0的有多少个bj要>k所以从大到小遍历        这样每次更新就可以计算后面的值了        */        if(!b[i]) continue;        for(int j=0;j<50010;j+=i)//当b中有i这个值时则i就会对后面判断有影响            bx.flip(j);    }}int main(){    int ncase;    scanf("%d",&ncase);    while(ncase--)    {        a.reset();        b.reset();        ans.reset();        bx.reset();        int n,m,q;        scanf("%d%d%d",&n,&m,&q);        for(int i=0;i<n;i++)        {            int x;            scanf("%d",&x);            a.set(x);        }        int tmp=0;        for(int j=0;j<m;j++)        {            int x;            scanf("%d",&x);            b.set(x);            tmp=max(tmp,x);//计算k最大值可以是多少        }        solve(tmp);        while(q--)        {            int x;            scanf("%d",&x);            printf("%d\n",ans[x]?1:0);        }    }}
原创粉丝点击