因为最多就13个非1数字出现,所以枚举2到3000,每个数字出现次数,中间的剪枝要注意的就是连乘之和不能大于6000,连乘之和已经大于6000或者还没选数字但是当前能选最小数字的平方已经大于6000就返回
(int)pow(13,1)在我的codeblocks上居然是12,一直不知道错哪里,结果是精度原因。。。。。。。。
#include <bits/stdc++.h>
#define eps 1e-14
#define pi acos(-1)
#define ll long long
#define RD T*(rand()*2-RAND_MAX)
#define Drand (long double)rand()/RAND_MAX
#define LINF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=5e5+50;
const long long mod=1e9+7;
ll MOD(ll a,ll m){return a>m?a%m+m:a;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ans[3005],A[3005],INV[3005];
ll qpow(ll a, ll b)
{
ll ans = 1;
a = a % mod;
while(b)
{
if(b&1) ans = ans * a % mod;
a = a*a % mod;
b >>= 1;
}
return ans;
}
int counts=0;
ll n=3000;
bool dfs(ll add,ll mul,ll x,ll sum,ll inv,int ff)
{
if(x==n+1 || add<=mul && sum>=2 && ff==0)
{
if(ff==1)return true;
ll num1=mul-add;
ll cnt=sum+num1;
if(cnt>n)return false;
ans[cnt]=(ans[cnt]+A[cnt]*inv%mod*INV[num1]%mod)%mod;
// if(cnt==3000){
// cout<<" add = "<<add<<" mul = "<<mul<<" x = "<<x<<" sum = "<<sum<<" cnt = "<<cnt<<
// " num1 = "<<num1<<" mid = "<<A[cnt]*inv%mod*INV[num1]%mod<<" inv = "<<inv<<endl;
// cout<<ans[cnt]<<endl;
// }
ff=1;
if(cnt==n)return true;
else{
cnt++;
ll a=add+x-1;
ll m=mul*(x-1);
if(m>2*n || m-a>n-cnt)return true;
}
if(x==n+1)return true;
}
for(ll i=0;qpow(x,i)*mul<=2*n;i++){
if(i!=0)ff=0;
// cout<<x<<" "<<i<<" "<<add<<" "<<mul<<" "<<qpow(x,i)<<endl;
int flag=dfs(add+x*i,mul*qpow(x,i),x+1,sum+i,inv*INV[i]%mod,ff);
if(flag==false)break;
}
return true;
}
int main()
{
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
A[0] = 1;
for(int i = 1; i <= 3000; i++) A[i] = A[i-1] * i % mod;
for(int i = 0; i <= 3000; i++) INV[i] = qpow(A[i], mod-2);
dfs(0,1,2,0,1,0);
cout<<(int)pow(13,1)<<endl;
// for(int i=2;i<=20;i++){
// cout<<ans[i]<<endl;
// }
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
printf("%lld\n",ans[n]);
}
return 0;
}