2017 Multi-University Training Contest - Team 5 1.Rikka with Candies(压位)

链接: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\n",Check(k));
85         }
86     }
87     return 0;
88 }

 

posted @ 2017-08-13 02:11  7391_KID  阅读(224)  评论(0编辑  收藏  举报