把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

【CF1139D】Steps to One(期望+莫比乌斯反演)

点此看题面

大致题意: 一个空数列,每次随机加入一个\(1\sim m\)的元素,直至数列中所有元素\(gcd=1\)。求期望长度。

期望

关于期望有一个著名的公式:

\[E(X)=\sum_{i\ge1}P(X\ge i) \]

这里的\(P(X\ge i)\)即为最终长度大于等于\(i\)的概率。

接下来的做法都要以这一公式为基础。

推式子

考虑最终长度大于等于\(i\),等价于长度为\(i-1\)的序列\(gcd\not=1\)的概率。

总方案数是非常好计算的,就是\(m^{i-1}\),因此我们只要求出长度为\(i-1\)的序列\(gcd=1\)的方案数就可以了。

这一步可以使用容斥,容斥系数就是莫比乌斯函数:(可参考此题:【BZOJ2440】[中山市选2011] 完全平方数

\[\sum_{j=1}^m\mu(j)\lfloor\frac mj\rfloor^i \]

整个式子就是:

\[1+\sum_{i\ge2}\frac{m^{i-1}-\sum_{j=1}^m\mu(j)\lfloor\frac mj\rfloor^{i-1}}{m^{i-1}} \]

观察到式子中的\(i\)都以\(i-1\)的形式出现,方便起见我们将所有\(i\)\(1\)得到:

\[1+\sum_{i\ge1}\frac{m^i-\sum_{j=1}^m\mu(j)\lfloor\frac mj\rfloor^i}{m^i} \]

\(j=1\)\(\mu(j)\lfloor \frac mj\rfloor^i=m^i\),因此我们单独提出这个式子,与前面的\(m^i\)抵消,得到:

\[1-\sum_{i\ge 1}\frac{\sum_{j=2}^m\mu(j)\lfloor\frac mj\rfloor^i}{m^i} \]

接下来就是喜闻乐见地调整枚举顺序:

\[1-\sum_{j=2}^m\mu(j)\sum_{i\ge1}(\frac{\lfloor\frac mj\rfloor}{m})^i \]

由于\(\frac{\lfloor\frac mj\rfloor}{m}\)显然是一个小于\(1\)的数,所以适用于公式\(\sum_{i\ge1} x^i=\frac{x}{1-x}\),因此得到:

\[1-\sum_{j=2}^m\mu(j)\frac{\frac{\lfloor\frac mj\rfloor}m}{1-\frac{\lfloor\frac mj\rfloor}m} \]

\[1-\sum_{j=2}^m\mu(j)\frac{\lfloor\frac mj\rfloor}{m-\lfloor\frac mj\rfloor} \]

这个式子可以除法分块\(O(\sqrt n)\)求解。(但好像没啥意义?除非出成多组数据)

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define X 1000000007
using namespace std;
int n,Pt,P[N+5],mu[N+5],s[N+5];
I int QP(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
I void Sieve()//线性筛预处理
{
	RI i,j;for(mu[1]=1,i=2;i<=n;++i)
		for(!P[i]&&(mu[P[++Pt]=i]=X-1),j=1;j<=Pt&&i*P[j]<=n;++j)
			if(P[i*P[j]]=1,i%P[j]) mu[i*P[j]]=X-mu[i];else break;
	for(i=1;i<=n;++i) s[i]=(s[i-1]+mu[i])%X;//预处理莫比乌斯函数前缀和
}
int main()
{
	RI l,r,t=1;for(scanf("%d",&n),Sieve(),l=2;l<=n;l=r+1)//除法分块
		r=n/(n/l),t=(1LL*(X-1)*(s[r]-s[l-1]+X)%X*(n/l)%X*QP(n-n/l,X-2)+t)%X;
	return printf("%d\n",t),0;
}
posted @ 2020-08-22 14:01  TheLostWeak  阅读(201)  评论(0编辑  收藏  举报