题目链接: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 }
时间: 2024-10-10 13:38:45