做法
先来填第一个数,为了保证(f(p))最大,第一个数分解一下为(prodlimits_{p_i}p_i^{k_i})使得(sumlimits_{k_i})最大
显然第一个数为(2^x3^y)且(y≤1),否则可以把(3^2)换成(2^3),故第一个数最多有两种选择
定义函数(Cout(x,y)=frac{n}{2^x3^y})为n以内含因子(2^x3^y)的个数
设(f_{i,x,y})为填到第(i)个数后(gcd_{j=1}^i a_i=2^x3^y)的方案数,显然最后的答案为(f_{n,0,0})
code
#include<bits/stdc++.h>
using namespace std;
typedef int LL;
const LL maxn=1e6+9,mod=1e9+7;
LL n;
LL f[maxn][21][2];
inline LL Pow(LL base,LL b){
LL ret(1);
while(b){
if(b&1) ret=ret*base; base=base*base; b>>=1;
}return ret;
}
inline LL Cout(LL x,LL y){
LL val(1<<x);
val*=(y?3:1);
return n/val;
}
int main(){
scanf("%d",&n);
LL p(0);
while((1<<p)<=n) ++p;
f[1][--p][0]=1;
if((1<<p-1)*3<=n) f[1][p-1][1]=1;
for(LL i=1;i<n;++i)
for(LL j=0;j<=p;++j){
for(LL k=0;k<=1;++k){
f[i+1][j][k]=(f[i+1][j][k]+1ll*f[i][j][k]*(Cout(j,k)-i))%mod;
if(j) f[i+1][j-1][k]=(f[i+1][j-1][k]+1ll*f[i][j][k]*(Cout(j-1,k)-Cout(j,k)))%mod;
if(k) f[i+1][j][k-1]=(f[i+1][j][k-1]+1ll*f[i][j][k]*(Cout(j,k-1)-Cout(j,k)))%mod;
}
}
printf("%d",f[n][0][0]);
return 0;
}