题意
存在两个长度分别为
n,m
的数组
A,B
。有
q
个询问,每个询问给出一个数字
分析
由于只需要求出种数的奇偶性,容易发现奇偶性的变化和2进制中亦或的结果相同。于是想到利用位操作来进行优化。对于
Bi
,可以不断的枚举区间
[kBi,(k+1)Bi−1]
,而这一段区间中值
kBi+d
对
Bi
取模的结果为
d
,即该区间对
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ULL unsigned long long
#define MAXN 50050
struct Bitset{
ULL bit[1600];
void reset(){
memset(bit,0,sizeof(bit));
}
void flip(int pos){
bit[pos>>6]^=1llu<<(pos&63);
}
bool judge(int pos){
return bit[pos>>6]&(1llu<<(pos&63));
}
void
}A,ans;
int b[MAXN];
ULL prebit[66];
int main(){
int T,n,m,q,a,mx;
cin>>T;
prebit[0]=1;
for(int i=1;i<64;++i)
prebit[i]=prebit[i-1]|(1ll<<i);
while(T--){
scanf("%d %d %d",&n,&m,&q);
A.reset();
ans.reset();
mx=0;
for(int i=0;i<n;++i){
scanf("%d",&a);
A.flip(a);
mx=max(a,mx);
}
for(int i=0;i<m;++i){
scanf("%d",&b[i]);
for(int j=0;j*b[i]<=mx;++j){
int len=j*b[i];
int idx1=len>>6,p1=len&63;
len+=b[i]-1;
int idx2=len>>6,p2=len&63;
if(idx1==idx2){
ULL tmp=A.bit[idx1]>>p1;
tmp&=prebit[p2-p1];
ans.bit[0]^=tmp;
}
else{
int curidx=0,curpos=0;
ULL tmp=A.bit[idx1]>>p1;
tmp&=prebit[63-p1];
ans.bit[0]^=tmp;
curpos=63-p1;
for(int k=idx1+1;k<idx2;++k){
if(curpos==63){
curidx++;
ans.bit[curidx]^=A.bit[k];
}
else{
tmp=A.bit[k]<<(curpos+1);
ans.bit[curidx++]^=tmp;
tmp=A.bit[k]>>p1;
tmp&=prebit[curpos];
ans.bit[curidx]^=tmp;
}
}
if(curpos==63){
curidx++;
tmp=A.bit[idx2]&prebit[p2];
ans.bit[curidx]^=tmp;
}
else{
if(p2<p1){
tmp=A.bit[idx2]&prebit[p2];
tmp<<=curpos+1;
ans.bit[curidx]^=tmp;
}
else{
tmp=A.bit[idx2]<<(curpos+1);
ans.bit[curidx++]^=tmp;
tmp=A.bit[idx2]>>p1;
tmp&=prebit[p2-p1];
ans.bit[curidx]^=tmp;
}
}
}
}
}
while(q--){
int k;
scanf("%d",&k);
if(ans.judge(k))
printf("1\n");
else
printf("0\n");
}
}
}