1. 程式人生 > >bitset(hdu 6085)

bitset(hdu 6085)

題意:給定兩個陣列a和b然後q次詢問,輸出ai%bi==k的個數的奇偶性。
思路:可以轉化為給a陣列每個都減去k求(ai-k)%bi==0的有多少個,又因為只有當bi>k時才會有結果所以可以預處理處所有的答案為k的結果最後O(1)輸出就好了。列舉k然後從大到小列舉bi每次都將bi的倍數統計出來
然後每次就可以算出(ai-k)%bi==0的有多少個了,具體的看程式碼和註釋。
這裡有一個關於bitset的用法及函式

#include<cstdio>
#include<cstring>
#include<bitset>
#include<iostream>
#include<algorithm> #define LL long long using namespace std; const int maxn=1e6+10; bitset<50010> a,b,ans,bx; void solve(int tmp) { for(int i=tmp;i>=0;i--)//列舉k { ans[i]=(bx&(a>>i)).count()&1; /* ans[i]存的是a[j]%b[j]==i的有多少個的奇偶性 bx[i]裡面是i%b[j]==0的奇偶性 a>>i相當於將所有的ai的值都減了i丟掉了<0的值 &1是判斷奇偶性的 判斷的是(ai-k)%bj==0的有多少個bj要>k所以從大到小遍歷 這樣每次更新就可以計算後面的值了 */
if(!b[i]) continue; for(int j=0;j<50010;j+=i)//當b中有i這個值時則i就會對後面判斷有影響 bx.flip(j); } } int main() { int ncase; scanf("%d",&ncase); while(ncase--) { a.reset(); b.reset(); ans.reset(); bx.reset(); int n,m,q; scanf
("%d%d%d",&n,&m,&q); for(int i=0;i<n;i++) { int x; scanf("%d",&x); a.set(x); } int tmp=0; for(int j=0;j<m;j++) { int x; scanf("%d",&x); b.set(x); tmp=max(tmp,x);//計算k最大值可以是多少 } solve(tmp); while(q--) { int x; scanf("%d",&x); printf("%d\n",ans[x]?1:0); } } }