题意:给定两个数组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 long
using 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);
}
}
}