hdu 6085 Rikka with Candies(bitset)

题目链接:hdu 6085 Rikka with Candies

题意:

给你一个A序列和B序列,A和B内的每个数都不相同,现在有q个询问,问对于每个询问的k输出A[i]%B[j]==k的个数的奇偶性。

题解:

考虑两种情况:

1. 当A[i]<B[i]时,对于当前询问的k,只要A[i]中有k,那么大于A[i]的数都会有贡献。

2. 当A[i]>=B[i]时,如果A[i]%B[j]==k,那么会有(A[i]-k)%B[j]=0。此时只要B[j]是A[i]-k的因子就会有贡献。

所以我们将询问从大到小排序,将大于k的B[j]是那些数的因子筛一下。

然后用bitset优化一下,将相同的询问优化掉。

所以最后的复杂度为O( 50000*log(50000)+50000*q/32)

 1 #include<bits/stdc++.h>
 2 #define mst(a,b) memset(a,b,sizeof(a))
 3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 4 using namespace std;
 5 typedef pair<int,int>P;
 6 
 7 const int N=5e4+7;
 8 int t,n,m,q,a[N],b[N],ans[N],sum[N],vis[N];
 9 bitset<N>ba,bb,tmp;
10 P ask[N];
11 
12 int main(){
13     scanf("%d",&t);
14     while(t--)
15     {
16         ba.reset(),bb.reset(),mst(vis,0);
17         scanf("%d%d%d",&n,&m,&q);
18         F(i,1,n)scanf("%d",a+i),ba[a[i]]=1;
19         F(i,1,m)scanf("%d",b+i),vis[b[i]]=1;
20         for(int i=50000;i>=0;i--)sum[i]=vis[i+1]^sum[i+1];
21         F(i,1,q)
22         {
23             scanf("%d",&ask[i].first);
24             ask[i].second=i;
25         }
26         sort(ask+1,ask+1+q,greater<P>());
27         int now=50000;
28         F(i,1,q)
29         {
30             int k=ask[i].first;
31             if(i>1&&k==ask[i-1].first)
32             {
33                 ans[ask[i].second]=ans[ask[i-1].second];
34                 continue;
35             }
36             while(now>k)
37             {
38                 if(vis[now])
39                     for(int j=now;j<=50000;j+=now)
40                         bb.flip(j);
41                 now--;
42             }
43             int cnt=(((ba>>k)&bb).count())&1;
44             if(ba[k])cnt^=sum[k];
45             ans[ask[i].second]=cnt;
46         }
47         F(i,1,q)printf("%d\n",ans[i]);    
48     }
49     return 0;
50 }
View Code

 

posted @ 2017-08-09 10:41  bin_gege  阅读(152)  评论(0编辑  收藏  举报