Rikka with Candies(bitset操作)

题意: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
using namespace std;
const int N=50005;

int a[N],b[N],k[N],ans[N];
bool flag[N];
bitset 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<

 

 

 

 

 

 

 

你可能感兴趣的:(数据结构,算法)