http://codeforces.com/contest/1139/problem/D
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+10;
const int mod=1e9+7;
ll f[maxn],n;
int pri[maxn],mu[maxn],is[maxn],cnt;
vector<int>ve[maxn];
int cal(int x,int y)//i 在 1-n gcd(x,i)=y;
{
int dd=x/y,res=0;
for(int i=0;i<ve[dd].size();i++)
{
int p=ve[dd][i];
res=res+mu[p]*(n/y)/p;
}
return res;
}
ll qpow(ll x,ll y)
{
ll res=1,k=x;
while(y)
{
if(y&1)res=res*k%mod;
k=k*k%mod;
y/=2;
}
return res;
}
int getu()
{
mu[1]=1;
for(int i=2;i<=n;++i)
{
if(!is[i])
{
pri[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt&&i*pri[j]<=n;++j)
{
is[i*pri[j]]=1;
if(i%pri[j])
mu[i*pri[j]]=-mu[i];
else
{
mu[i*pri[j]]=0;
break;
}
}
}
}
void init()
{
getu();
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j+=i)ve[j].push_back(i);
}
int main()
{
ll ans=0;
scanf("%d",&n);
init();
for(int i=1;i<=n;i++)
{
f[i]=n;
for(int j=0;j<ve[i].size();j++)
{
int d=ve[i][j];
if(i==d)continue;
f[i]=(f[i]+f[d]*cal(i,d)%mod)%mod;
}
f[i]=f[i]*qpow(n-cal(i,i),mod-2)%mod;
ans=(ans+f[i])%mod;
}
printf("%d\n",(ans*qpow(n,mod-2)%mod+1)%mod);
return 0;
}
codeforces#1139D. Steps to One (概率dp+莫比乌斯)
原文:https://www.cnblogs.com/carcar/p/10689260.html