The meaning of problems
Consider \ (n = 1 \) case, we understood from Theorem Shu Pei, \ (K * A_1 \% P \) can be expressed \ (\ gcd (a_1, P ) \) all multiples.
Is the same reason the number of the plurality of extended (not permit): \
((k_1a_1 k_2a_2 + + ... + k_na_n) \% P \) , indicative of \ (\ gcd (a_1, a_2 , ..., a_n) \ ) all multiples.
Thus Order \ (v_i = \ gcd (v_i , P) \) after the problem is equivalent.
After processing the \ (P \) Number of all about, assumed that the number of \ (m \) , the presence \ (A \) array.
Set \ (f_ {i, j} \) represents consideration \ (P \) before (I \) \ a divisor, extracted number \ (\ GCD \) of \ (a_j \) program number, \ (cnt_i \) represents \ (a_i \) the divisor in \ (v \) (take off \ (\ gcd \) the number appearing in).
\ (I {F_, F_ K = {} +. 1-I, J} * (2 ^ {-1} cnt_i) \)
\ (F_ {I, I +} = 2 ^ {-1} cnt_i \)
After For each \ (W_i \) , we enumerate submultiple:
\ (ANS = \ SUM \ {a_i limits_ |} F_ {n-W, I} \) .
But this inquiry \ (mq \) , we want to further optimize:
find \ (a_i \) is \ (P \) about the number, so \ (a_i | (\ gcd (P, w)) \) , so you can so \ (= W \ GCD (W, P) \) .
We pretreated \ (G_i = \ SUM \ limits_ a_j {|} F_ {n-a_i, J} \) , so that you can \ (O (1) \) processing each asked.
code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int maxm=5e4+10;
const int mod=1e9+7;
int n,m,P,Q;
int a[maxm],val[maxn],cnt[maxm],pw[maxn],g[maxm];
int f[2][maxm];
int main()
{
scanf("%d%d%d",&n,&Q,&P);
for(int i=1;i<=n;i++)scanf("%d",&val[i]),val[i]=__gcd(val[i],P);
for(int i=1;i*i<=P;i++)
{
if(P%i)continue;
a[++m]=i;
if(P!=i*i)a[++m]=P/i;
}
sort(a+1,a+m+1);
for(int i=1;i<=n;i++)cnt[lower_bound(a+1,a+m+1,val[i])-a]++;
pw[1]=2;
for(int i=2;i<=n;i++)pw[i]=1ll*pw[i-1]*2%mod;
for(int i=1;i<=n;i++)pw[i]=(pw[i]-1+mod)%mod;
for(int i=1;i<=m;i++)
{
int now=i&1;
for(int j=1;j<=m;j++)f[now][j]=f[now^1][j];
for(int j=1;j<i;j++)
{
int k=__gcd(a[i],a[j]);
k=lower_bound(a+1,a+m+1,k)-a;
f[now][k]=(f[now][k]+1ll*f[now^1][j]*pw[cnt[i]]%mod)%mod;
}
f[now][i]=(f[now][i]+pw[cnt[i]])%mod;
}
for(int i=1;i<=m;i++)
for(int j=1;j<=i;j++)
if(a[i]%a[j]==0)g[i]=(g[i]+f[m&1][j])%mod;
while(Q--)
{
int k;scanf("%d",&k);
k=__gcd(k,P);
printf("%d\n",g[lower_bound(a+1,a+m+1,k)-a]);
}
return 0;
}