后三个点RE
/*
5/8 20:00 开始敲
5/8 20:36 有数了 15 16 16
5/8 20:40 7 8 8
5/8 20:49 5 6 6 过样例啦 然后 0 分
5/12 15:18 40分啦 num[a[i]]-->num[i]
5/12 15:23 70分 (1<<num[a[i])num[a[i]]太大,位运算干不了,可以用数组取摸,后三个点RE
*/
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define int long long
using namespace std;
const int A = 1e7+10;
const int B = 1e7+10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
inline int read() {
char c = getchar();
int x = 0, f = 1;
for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
}
int js;//记录删除后的书
map<int,int>lsh;//离散化用
int pre[B],cnt;//处理因子
int num[B];//记录相同的重量出现的个数
int n,p,f[5000][5000],a[B],t;
int gcd(int x,int y) {return y==0 ? x : gcd(y,x%y);}
void prepare()//知道因子
{
for (int i=1;i*i<=p;i++)
{
if (p%i==0)
{
pre[++cnt]=i;
if (i*i==p) continue;
pre[++cnt]=p/i;
}
}
sort(pre+1,pre+cnt+1);
for (int i=1;i<=cnt;i++)
{
lsh[pre[i]]=i;
}
}
int pow2[B];
main()
{
n=read(); t=read(); p=read();
pow2[0]=1;
for (int i=1;i<=10000;i++)
pow2[i]=pow2[i-1]*2%mod;
for (int i=1;i<=n;i++)
{
int x=read();
int s=gcd(x,p);
if (!num[s]) a[++js]=s;//保证没有重复的数了
num[s]++;//计数用
}
prepare();//处理因子
for (int i=1;i<=js;i++)
for (int j=1;j<=cnt;j++)
{
(f[i][lsh[pre[j]]]+=f[i-1][lsh[pre[j]]])%=mod;//选
if (pre[j]==a[i]) f[i][lsh[pre[j]]]+=(pow2[num[a[i]]]%mod-1)%mod;
int k=lsh[gcd(pre[j],a[i])];
(f[i][k]+=1ll*f[i-1][j]*((pow2[num[a[i]]])-1)%mod)%=mod;
f[i][lsh[pre[j]]]%=mod;
f[i][k]%=mod;
}
while (t--)
{
int w=read();
int ans=0;
for (int i=1;i<=cnt;i++)
{
if (w%pre[i]==0)
(ans+=f[js][lsh[pre[i]]])%=mod;
}
printf("%lld\n",ans%mod);
}
}