比赛 |
HAOI 2018 Day1 |
评测结果 |
AAAAAAAA |
题目名称 |
奇怪的背包 |
最终得分 |
100 |
用户昵称 |
ZRQ |
运行时间 |
0.101 s |
代码语言 |
C++ |
内存使用 |
4.34 MiB |
提交时间 |
2022-04-11 11:54:54 |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int N=1000005,M=10005,mod=1e9+7;
int n,q,P,v[N],w[N],p[M],tot,ct[M],f[2][M],sum[N],ans[M];
char ch;
inline void read(int &x){x=0;ch=getchar();while(ch<48||ch>57)ch=getchar();while(ch>47&&ch<58)x=(x<<3)+(x<<1)+(ch^48),ch=getchar();}
inline int gcd(int m,int n)
{
int t;
while(n) t=m%n,m=n,n=t;
return m;
}
int main()
{
freopen("knapsack.in","r",stdin);
freopen("knapsack.out","w",stdout);
int now=0,k;
read(n),read(q),read(P);
for(int i=1;i<=n;++i)
read(v[i]),v[i]=gcd(v[i],P);
sum[1]=2;
for(int i=2;i<=n;++i) sum[i]=sum[i-1]*2%mod;//预处理2的幂
for(int i=1;i<=n;++i) sum[i]=(sum[i]+mod-1)%mod;
for(int i=1;i<=sqrt(P);++i)//求P的质因子并保持有序
if(P%i==0)
p[++tot]=i;
for(int i=tot;i>1;--i)
if(P/p[i]!=p[i])
p[++tot]=P/p[i];
for(int i=1;i<=n;++i)
{
int pos=lower_bound(p+1,p+tot+1,v[i])-p;
++ct[pos];
}
for(int i=1;i<=tot;++i)
if(ct[i])
{
now^=1;
for(int j=1;j<=tot;++j) f[now][j]=f[now^1][j];
for(int j=1;j<=tot;++j)
if(f[now^1][j])
{
int npos=lower_bound(p+1,p+tot+1,gcd(p[i],p[j]))-p;
f[now][npos]+=1LL*f[now^1][j]*sum[ct[i]]%mod;
f[now][npos]%=mod;
}
f[now][i]+=sum[ct[i]]%mod;
f[now][i]%=mod;
}
for(int i=1;i<=tot;++i)
for(int j=1;j<=i;++j)
if(p[i]%p[j]==0)
ans[i]+=f[now][j],ans[i]%=mod;
for(int i=1;i<=q;++i)
{
read(k);
k=gcd(k,P);
int pos=lower_bound(p+1,p+tot+1,k)-p;
printf("%d\n",ans[pos]);
}
return 0;
}