其他分享
首页 > 其他分享> > #莫比乌斯反演,期望#CF1139D Steps to One

#莫比乌斯反演,期望#CF1139D Steps to One

作者:互联网

题目

每次随机选一个 \(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);
}

标签:lfloor,right,frac,sum,mu,反演,Steps,CF1139D,left
来源: https://www.cnblogs.com/Spare-No-Effort/p/15900575.html