题意
一个序列会不断随机产生 [ 1 , m ] [1,m] [1,m]之间的一个正整数添加在序列的最后,求整个序列中所有数的最大公约数为 1 1 1时序列长度的期望.
题解
我们先思考转移.很显然
d
p
[
k
]
=
∑
i
=
1
m
d
p
[
g
c
d
(
i
,
k
)
]
m
+
1
dp[k]=\frac{\sum_{i=1}^{m}dp[gcd(i,k)]}{m}+1
dp[k]=m∑i=1mdp[gcd(i,k)]+1
但是这样做我们可以成功得到优越的
m
2
l
o
g
(
m
)
m^2log(m)
m2log(m)超时算法.
考虑使用容斥进行优化.
一般的数论容斥完全看不懂,我就学了一下莫比乌斯反演.
首先运用各种方法筛出
μ
\mu
μ函数,然后开始思考
[
2
,
m
]
[2,m]
[2,m]的每一个数字的贡献.
令
f
x
=
[
m
x
]
m
−
[
m
x
]
(
m
以
内
x
的
倍
数
的
个
数
/
m
以
内
非
x
的
倍
数
的
数
的
个
数
)
f_x=\frac{[\frac{m}{x}]}{m-[\frac{m}{x}]}(m以内x的倍数的个数/m以内非x的倍数的数的个数)
fx=m−[xm][xm](m以内x的倍数的个数/m以内非x的倍数的数的个数)
则可得答案为
−
∑
i
=
2
m
μ
i
f
i
+
1
-\sum_{i=2}^m\mu_if_i+1
−∑i=2mμifi+1.
写出公式即可.
const int yuzu=2e5,mod=1e9+7;
typedef int fuko[yuzu|10];
fuko mu={0,1};
ll kasumi(ll a,ll b=mod-2) {
ll zw=1;
for (;b;b>>=1,a=a*a%mod) if (b&1) zw=zw*a%mod;
return zw;
}
int main() {
int i,j,n=read();
for (i=1;i<=n;++i)
for (j=i<<1;j<=n;j+=i) mu[j]-=mu[i];
ll zw=1;
for (i=2;i<=n;++i)
zw=(zw-mu[i]*(n/i)%mod*kasumi(n-n/i)%mod+mod)%mod;
printf("%lld\n",zw);
}
谢谢大家.