题目:传送门走起
之前有做过一个类似的题目,再来一个传送门,最后公式的推导结果就是求n的素因子个数,那么这个题也类似,就是求n!的素因子个数,这一点还是参考了网上的资料:参考链接
n!可以表示为n!=k^m*m!*a其中k为这个素因子,m为含有这个素因子的数量,a为不含有这个素因子的其它数的乘积,然后再对m使用相同的方法,最终就可以得到k这个素因子的个数了这个公式十分好理解,随便找个数举一下例子就可以得到,比如8!=8*7*6*5*4*3*2*1,现在我们来求2的这个素因子的个数,那8!=2^4*4!*105=2^6*2!*315=2^7*315,这样就得到了8!含有2这个素因子的个数为7,这个方法代码实现起来也很容易,因为可以发现公式中的m正好就是n/k,所以一直累加n/k,便可以得到n中含有几个k
int count(int n,int k)
{
int num=0;
while(n)
{
num+=n/k;
n/=k;
}
return num;
}
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e6+5;
const int mod=1e9+7;
bool temp[N];
int data[N/10];
int cnt=0;
void prime()
{
temp[2]=true;
for(int i=3;i<N;i+=2)
{
temp[i]=true;
temp[i+1]=false;
}
for(int i=3;i<N;i+=2)
if(temp[i])
for(int j=i+i;j<N;j+=i) temp[j]=false;
for(int i=2;i<N;i++)
{
if(temp[i]) data[cnt++]=i;
}
}
ll quickmod(ll a,ll b,ll m)
{
ll t=1;
while(b)
{
if(b%2==1)
{
t=t*a%m;
}
b=b/2;
a=a*a%m;
}
return t;
}
ll fun(ll a)
{
ll ans=1;
for(ll i=0;i<cnt&&data[i]<=a;i++)
{
ll c=0;
ll n=a;
/*求n!中因子data[i]的个数*/
while(n)
{
c+=n/data[i];
n/=data[i];
}
ans=ans*(2*c+1)%mod;
}
/*2的逆元*/
ll mod_=quickmod(2,mod-2,mod);
ans=(ans+1)*mod_%mod;
return ans%mod;
}
int main()
{
prime();
ll n;
while(scanf("%lld",&n)!=-1)
{
printf("%lld\n",fun(n));
}
return 0;
}