设 S=∏ki=1pi,n=∑xipi S = ∏ i = 1 k p i , n = ∑ x i p i 。
可以发现 k k 最多只有 7 7 。
先将 n n 减去 ∑pi ∑ p i ,保证 lcm=S l c m = S 。
将 xi x i 表示为 a⋅Spi+b ( b<Spi ) a · S p i + b ( b < S p i ) ,这样每一组 (a,b) ( a , b ) 都是一种方案。
将 n n 也拆分成 nS n S 和 n mod S n m o d S 两部分。显然 n mod S n m o d S 只能用 b b 填。枚举 nS n S 中有几个由 b b 填,多重背包预处理下,剩下的就可以直接算了。
#include
using namespace std;
typedef long long ll;
const int N=2000010;
const int M=1000000007;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void Read(int& x){
char c=nc();
for(;c<'0'||c>'9';c=nc());
for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
}
inline void Read(ll& x){
char c=nc();
for(;c<'0'||c>'9';c=nc());
for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
}
ll n;
int k,m,T,s;
int cnt;
int Ans;
int p[N],num,sum;
int inv[10];
int a[10];
int f[N<<3],g[N<<3],mx;
bool b[N];
inline void Add(int& x,int y){
x=(x+y)%M;
}
inline bool Init(){
for(int i=2;i<=s;i++){
if(!b[i]){
p[++num]=i;
if(!(s%i)){
sum+=i;a[++cnt]=i;
if(1ll*i*i<=s&&!(s%(i*i)))return 0;
}
}
int t;
for(int j=1;j<=num&&(t=p[j]*i)<=s;j++){
b[t]=1;
if(!(i%p[j]))break;
}
}
inv[0]=inv[1]=1;
for(int i=2;i<=9;i++)inv[i]=1ll*inv[M%i]*(M-M/i)%M;
for(int i=3;i<=9;i++)inv[i]=1ll*inv[i-1]*inv[i]%M;
return 1;
}
inline void DP(){
mx=cnt*s;
f[0]=1;
for(int i=1;i<=cnt;i++){
for(int j=0;jint t=0;
for(int k=j;k<=mx;k+=a[i]){
Add(t,f[k]);
if(k>=s)Add(t,-f[k-s]);
g[k]=t;
}
}
memcpy(f,g,sizeof(g));
}
}
inline int C(ll n,int m){
int Ans=1;
for(ll i=n-m+1;i<=n;i++)Ans=i%M*Ans%M;
Ans=1ll*Ans*inv[m]%M;
return Ans;
}
int main(){
Read(s);Read(T);
if(!Init()){
while(T--)printf("0\n");
return 0;
}
DP();
while(T--){
Read(n);
n-=sum;
if(n<0){
printf("0\n");
continue;
}
Ans=0;
ll x=n/s;int y=n%s;
for(int i=0;i*s+y<=mx&&i<=x;i++)Add(Ans,1ll*f[i*s+y]*C(x-i+cnt-1,cnt-1)%M);
printf("%d\n",(Ans+M)%M);
}
return 0;
}