版权声明:虽然博主很菜,但是还是请注明出处(我觉得应该没人偷我的博客) https://blog.csdn.net/qq_43346903/article/details/88012366
裴蜀定理:
所以对于
,有
会产生贡献
对于
,其实是查询
1e9 的约数最多1e3个
所以dp预处理,
表示到第
个物品,gcd为
的方案数
Code:
#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define ll long long
#define mod 1000000007
using namespace std;
using namespace tr1;
inline int read(){
int res=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
return res*f;
}
inline int add(int x,int y){x+=y;if(x>=mod) x-=mod;return x;}
unordered_map<int,int>f[2],ans,a;
unordered_map<int,int>::iterator x,y;
int n,m,p;
void dp(){
int now=0,nxt=f[0][p]=1;
int cnt=0;
for(x=a.begin();x!=a.end();x++){
f[nxt].clear(),++cnt;
for(y=f[now].begin();y!=f[now].end();y++){
f[nxt][y->first]=add(f[nxt][y->first],y->second);
f[nxt][__gcd(y->first,x->first)]=add(f[nxt][__gcd(y->first,x->first)],add(x->second,mod-1)*(ll)y->second%mod);
}
now=nxt,nxt^=1;
}
for(int i=1;i*(ll)i<=p;i++) if(!(p%i)) ans[i]=ans[p/i]=0;
for(x=ans.begin();x!=ans.end();x++)
for(y=f[now].begin();y!=f[now].end();y++) if(!(x->first%y->first)) x->second=add(x->second,y->second);
}
int main(){
n=read(),m=read(),p=read();
for(int i=1;i<=n;i++){
int gcdd=__gcd(read(),p);
if(!a[gcdd]) a[gcdd]=2;
else (a[gcdd]*=2)%=mod;
}
dp();
while(m--) cout<<ans[__gcd(read(),p)]<<"\n";
}