题目
每次随机选一个 \(1\) 到 \(m\) 之间的数加在数列末尾,
数列中所有数的 \(\gcd=1\) 时停止,求数列期望长度。\(m\leq 10^5\)
分析
求期望长度的一种方法就是枚举长度然后将概率相加,也即是 \(E(X)=\sum_{i=1}P(X\geq i)=1+\sum_{i=1}P(X>i)\),容斥一下
\[P(X>i)=1-\frac{[\gcd==1]}{m^i}=1-\frac{\sum_{d=1}^m\mu(d)\left\lfloor\frac{m}{d}\right\rfloor^i}{m^i}=-\frac{\sum_{d=2}^m\mu(d)\left\lfloor\frac{m}{d}\right\rfloor^i}{m^i} \]那么
\[E(X)=1-\sum_{i=1}\sum_{d=2}^m\mu(d)\left(\frac{\left\lfloor\frac{m}{d}\right\rfloor}{m}\right)^i=1-\sum_{d=2}^m\frac{\mu(d)\left\lfloor\frac{m}{d}\right\rfloor}{m-\left\lfloor\frac{m}{d}\right\rfloor} \]直接 \(O(m)\) 求就可以了
代码
#include <cstdio>
#define rr register
using namespace std;
const int mod=1e9+7,N=100011;
int n,mu[N],prime[N],inv[N],cnt,ans; bool v[N];
signed main(){
scanf("%d",&n),mu[1]=inv[1]=inv[0]=ans=1;
for (rr int i=2;i<=n;++i){
inv[i]=1ll*inv[mod%i]*(mod-mod/i)%mod;
if (!v[i]) mu[i]=-1,prime[++cnt]=i;
for (rr int j=1;j<=cnt&&i<=n/prime[j];++j){
v[i*prime[j]]=1;
if (i%prime[j]==0) break;
mu[i*prime[j]]=-mu[i];
}
}
for (rr int i=2;i<=n;++i)
ans=(ans-1ll*mu[i]*(n/i)*inv[n-n/i]%mod)%mod;
return !printf("%d",(ans+mod)%mod);
}