bitset(hdu 6085)
阿新 • • 發佈:2018-12-24
題意:給定兩個陣列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);
}
}
}