链接:http://acm.hdu.edu.cn/showproblem.php?pid=6085
题意:给定长度分别为n,m的数组A和B,给定q个询问,每次询问给出一个k,求满足Ai%Bj=k的数对(i,j)的个数,结果mod2。
题解:
分析:简单说就是枚举Bi的倍数,在对应区间内得到k的个数,加到答案上,复杂度是O(n^2)。由于答案只需要mod2,因此可以用压位来达到一个常数/32的优化,就可以过了。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define Max(x,y) x>=y?x:y 5 using namespace std; 6 typedef unsigned long long ull; 7 const int maxn=5e4+5; 8 const ull r=(((ull)1<<6)-1); 9 int n,m,mx,a,t,q,k; 10 ull b[maxn/64+5],ans[maxn/64+5]; 11 ull B[maxn]; 12 void init(){ 13 memset(ans,0,sizeof(ans)); 14 memset(b,0,sizeof(b)); 15 mx=0; 16 } 17 void add(int s,int t,int mod){ 18 ull d1=64-(s&r),d2=s&r,q,p; 19 if(t>mx)t=mx; 20 int c=0; 21 while(s+64<=t){ 22 ans[c]^=b[s>>6]>>d2; 23 q=b[(s>>6)+1]<<d1; 24 if(d1==64)q=0; 25 ans[c]^=q; 26 c++; 27 s+=64; 28 } 29 if(s>>6!=t>>6){ 30 ans[c]^=b[s>>6]>>d2; 31 q=(((ull)1<<((t&r)+1))-1); 32 if((t&r)==63)q=~(ull)0; 33 q=(b[t>>6]&q)<<d1; 34 if(d1==64)q=0; 35 ans[c]^=q; 36 }else{ 37 q=(((ull)1<<((t&r)+1))-1); 38 if((t&r)==63)q=~(ull)0; 39 p=(b[s>>6]&q); 40 ans[c]^=(p>>d2); 41 } 42 } 43 int Check(int loca){ 44 return (ans[loca>>6]&((ull)1<<(loca&((1<<6)-1))))?1:0; 45 } 46 //int aa[maxn],kk[maxn]; 47 //int test(){ 48 // memset(kk,0,sizeof(kk)); 49 // for(int i=0;i<n;i++){ 50 // for(int j=0;j<m;j++){ 51 // kk[aa[i]%B[j]]++; 52 // cout<<aa[i]%B[j]<<' '; 53 // } 54 // cout<<endl; 55 // } 56 // for(int i=0;i<maxn;i++){ 57 // kk[i]%=2; 58 // } 59 //} 60 int main(){ 61 // freopen("e:\out.txt","w",stdout); 62 // freopen("e:\in.txt","r",stdin); 63 scanf("%d",&t); 64 while(t--){ 65 init(); 66 scanf("%d%d%d",&n,&m,&q); 67 for(int i=0;i<n;i++){ 68 scanf("%d",&a); 69 mx=Max(mx,a); 70 b[a>>6]^=(ull)1<<(a&((1<<6)-1)); 71 // aa[i]=a; 72 } 73 for(int i=0;i<m;i++) 74 scanf("%d",&B[i]); 75 for(int i=0;i<m;i++){ 76 for(int l=0;(ull)l*B[i]<=mx;l++){ 77 add(l*B[i],(l+1)*B[i]-1,B[i]); 78 } 79 } 80 // test(); 81 for(int i=0;i<q;i++){ 82 scanf("%d",&k); 83 // printf("%d %d ",i,kk[k]); 84 printf("%d ",Check(k)); 85 } 86 } 87 return 0; 88 }