分析:
至今仍然不知道。。。为什么N以内的,是L的因数且是G的倍数的数不超过1000个。。。
缸道理不应该是 N \sqrt N N个吗。。。
看来是我孤陋寡闻了。。。。
合并的时候用一下FWT
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 1010
#define MAXS 65556
#define MOD 1000000007
#define MAXQ 100010
using namespace std;
void Read(int &x){
char c;
while(c=getchar(),c!=EOF&&(c<'0'||c>'9'));
x=c-'0';
while(c=getchar(),c!=EOF&&c>='0'&&c<='9')
x=x*10+c-'0';
}
map<int,int> f;
vector<int> pr,tp;
int N,G,L,Q;
int a[MAXQ],fac[MAXN];
int dp1[MAXN][MAXS],dp2[MAXN][MAXS],res[MAXS*4];
int masks[MAXN],n;
int ans[MAXN];
void FWT(int A[],int N){
for(int i=1;i<N;i<<=1)
for(int j=0;j<N;j+=(i<<1))
for(int k=0;k<i;k++){
A[i+j+k]=A[i+j+k]+A[j+k];
if(A[i+j+k]>=MOD)
A[i+j+k]-=MOD;
}
}
void IFWT(int A[],int N){
for(int i=1;i<N;i<<=1)
for(int j=0;j<N;j+=(i<<1))
for(int k=0;k<i;k++){
A[i+j+k]=A[i+j+k]-A[j+k];
if(A[i+j+k]<0)
A[i+j+k]+=MOD;
}
}
void Mul(int A[],int B[],int N,int M,int res[]){
// int p=1;
// while(p<=N+M)
// p<<=1;
FWT(A,N);
FWT(B,N);
for(int i=0;i<N;i++)
res[i]=1ll*A[i]*B[i]%MOD;
IFWT(res,N);
}
int main(){
SF("%d%d%d",&N,&G,&L);
SF("%d",&Q);
for(int i=1;i<=Q;i++)
Read(a[i]);
// SF("%d",&a[i]);
if(L%G){
for(int i=1;i<=Q;i++)
PF("0\n");
return 0;
}
L/=G,N/=G;
for(int i=1;1ll*i*i<=1ll*L;i++)
if(L%i==0){
if(i<=N)
fac[++n]=i;
if(L/i<=N&&i*i!=L)
fac[++n]=L/i;
}
sort(fac+1,fac+1+n);
for(int i=1;i<=n;i++)
f[fac[i]]=i;
for(int i=2;1ll*i*i<=1ll*L;i++)
if(L%i==0){
pr.push_back(i);
int tot=0;
while(L%i==0){
tot++;
L/=i;
}
tp.push_back(tot);
}
if(L!=1){
pr.push_back(L);
tp.push_back(1);
}
int m=pr.size();
for(int i=1;i<=n;i++){
int val=fac[i];
for(int j=0;j<m;j++){
if(val%pr[j]==0){
int tot=0;
while(val%pr[j]==0){
tot++;
val/=pr[j];
}
if(tot==tp[j])
masks[i]|=(1<<(2*j+1));
}
else
masks[i]|=(1<<(2*j));
}
}
dp1[0][0]=1;
for(int i=0;i<n;i++)
for(int j=0;j<(1<<(2*m));j++){
(dp1[i+1][j|masks[i+1]]+=dp1[i][j])%=MOD;
(dp1[i+1][j]+=dp1[i][j])%=MOD;
}
dp2[n+1][0]=1;
for(int i=n+1;i>=2;i--)
for(int j=0;j<(1<<(2*m));j++){
(dp2[i-1][j|masks[i-1]]+=dp2[i][j])%=MOD;
(dp2[i-1][j]+=dp2[i][j])%=MOD;
}
for(int i=1;i<=n;i++){
Mul(dp1[i-1],dp2[i+1],(1<<(2*m)),(1<<(2*m)),res);
for(int j=0;j<(1<<(2*m));j++)
if((j|masks[i])==(1<<(2*m))-1)
(ans[i]+=res[j])%=MOD;
}
for(int i=1;i<=Q;i++){
if(a[i]%G){
PF("0\n");
continue;
}
else
a[i]/=G;
if(f.count(a[i])==0)
PF("0\n");
else{
PF("%d\n",ans[f[a[i]]]);
}
}
}