大致题意: 一个空数列,每次随机加入一个(1sim m)的元素,直至数列中所有元素(gcd=1)。求期望长度。
期望
关于期望有一个著名的公式:
[E(X)=sum_{ige1}P(Xge i)
]
这里的(P(Xge i))即为最终长度大于等于(i)的概率。
接下来的做法都要以这一公式为基础。
推式子
考虑最终长度大于等于(i),等价于长度为(i-1)的序列(gcd ot=1)的概率。
总方案数是非常好计算的,就是(m^{i-1}),因此我们只要求出长度为(i-1)的序列(gcd=1)的方案数就可以了。
这一步可以使用容斥,容斥系数就是莫比乌斯函数:(可参考此题:【BZOJ2440】[中山市选2011] 完全平方数)
[sum_{j=1}^mmu(j)lfloorfrac mj
floor^i
]
整个式子就是:
[1+sum_{ige2}frac{m^{i-1}-sum_{j=1}^mmu(j)lfloorfrac mj
floor^{i-1}}{m^{i-1}}
]
观察到式子中的(i)都以(i-1)的形式出现,方便起见我们将所有(i)加(1)得到:
[1+sum_{ige1}frac{m^i-sum_{j=1}^mmu(j)lfloorfrac mj
floor^i}{m^i}
]
当(j=1)时(mu(j)lfloor frac mj floor^i=m^i),因此我们单独提出这个式子,与前面的(m^i)抵消,得到:
[1-sum_{ige 1}frac{sum_{j=2}^mmu(j)lfloorfrac mj
floor^i}{m^i}
]
接下来就是喜闻乐见地调整枚举顺序:
[1-sum_{j=2}^mmu(j)sum_{ige1}(frac{lfloorfrac mj
floor}{m})^i
]
由于(frac{lfloorfrac mj floor}{m})显然是一个小于(1)的数,所以适用于公式(sum_{ige1} x^i=frac{x}{1-x}),因此得到:
[1-sum_{j=2}^mmu(j)frac{frac{lfloorfrac mj
floor}m}{1-frac{lfloorfrac mj
floor}m}
]
[1-sum_{j=2}^mmu(j)frac{lfloorfrac mj
floor}{m-lfloorfrac mj
floor}
]
这个式子可以除法分块(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
",t),0;
}