题意:A数组n个数,B数组m个数,q个查询, 每次给出一个k,询问有多少对(i,j), 使得Ai % Bj = k, 输出对数对模2的值
这道题可以用bitset来做,bitset与数组类似,但其中每一位只能为0或1,用来存储2进制的每一位
用整值类型将第27 位设置为1, 我们这样写
quiz1 |= 1<<27;
而用bitset 来做我们可以写
quizl[ 27 ] = 1;
或
quiz1.set( 27 );
用两个bitset类来进行操作,第一个ac ,ac.set(i)表示ac中第i位赋值1,用来表示i这个数字是否存在
ans[i]= ( bs & (ac>>i) ).count() &1; ac向右移了i位,即相当与ac中的每个数都减去了i,这就是bitset的方便之处。
& 运算符 只有两个数都为1才是1, ac和bs两个bitset &一波,就是ac和bs中每一位都相&
返回的是一个bitset 再count(),得到的是这个bitset中1的个数,最后再&1,相当于%2
第二个bs用来存储一系列的被余的数,注意到最终结果%2,所以 bs.flip(j); 这一步可以反转抵消,
例如a为8 b有6和3,那么8%6 和8%3都为2,那么贡献一共有2种,%2后和0是一样的。
#include<bits/stdc++.h>
using namespace std;
const int N=50005;
int a[N],b[N],k[N],ans[N];
bool flag[N];
bitset<N> bs,ac;
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int t,n,m,q;
int maxk;
cin>>t;
while(t--)
{
ac.reset();//ac中每一位赋0
bs.reset();
memset(flag,0,sizeof(flag));
maxk=0;
cin>> n >> m >> q;
for(int i=1;i<=n;i++)
{
cin>>a[i];
ac.set(a[i]);//ac中第a[i]位设为1
}
for(int i=1;i<=m;i++)
{
cin>>b[i];
flag[b[i]]=true;
maxk=max(maxk,b[i]);
}
for(int i=1;i<=q;i++)
{
cin>>k[i];
}
for(int i=maxk;i>=0;i--)
{
ans[i]= ( bs & (ac>>i) ).count() &1;
if(flag[i])
{
for(int j=0;j<=maxk;j+=i)
{
bs.flip(j);//把bc中第j位反转,0变1,1变0
}
}
}
for(int i=1;i<=q;i++)
{
cout<<ans[k[i]]<<endl;
}
}
}