简单的函数题解
简单的函数题解
一个数\(x\),其\(f[x]=f[y]+1\)
设\(lcm[y]=gcd(1,2,3,4,...,y)\)
则当且仅当\(lcm[y-1] \mid x,lcm[y] \nmid x\)
所以区间内答案为\(f[x]+1\)的为\(lcm[y-1]\)的倍数个数\(-lcm[y]\)的倍数个数
我们发现\(lcm[43]>=10^{18}\)
所以预处理出\(f[2]~f[43]\)
再统计\(f[x]=i\)的\(x\)个数,
最后快速幂求解。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int M=56;
const ll mod=1e9+7;
ll n,t,f[M],lcm[M],cnt[M],ans=1;
ll num(ll l,ll r,ll x){return r/x-(l-1)/x;}
ll ksm(ll base,ll v){
ll answer=1;
while(v){
if(v&1) answer=answer*base%mod;
base=base*base%mod,v>>=1;
}
return answer;
}
ll gcd(ll u,ll v){return !v?u:gcd(v,u%v);}
int main(){
scanf("%lld",&n),f[2]=1,lcm[1]=1,t=2;
for(ll i=2;i<=43;++i){
t=i,lcm[i]=lcm[i-1]/gcd(lcm[i-1],i)*i;
if(lcm[i]>=n) break;
}
for(int i=3;i<=43;++i) for(int j=2;j<i;++j) if(i%j){f[i]=f[j]+1; break;}
for(int i=2;i<=t;++i) cnt[f[i]+1]+=num(t+1,n,lcm[i-1])-num(t+1,n,lcm[i]);
for(int i=2;i<=t;++i) ++cnt[f[i]];
for(int i=2;i<=5;++i) ans=ans*ksm(i,cnt[i])%mod;
printf("%lld\n",ans);
return 0;
}