CF1139D Steps to One
喵喵题:
题意
给一个数列,每次随机选一个 \(1\) 到 \(m\) 之间的数加在数列末尾,数列中所有数的 \(gcd = 1\) 时停止,求期望长度, \(m \le 1e5\)
题解
看到期望,可以用全概率公式把界限变宽,\(f(x)\) 表示长度 \(\ge x\) 概率
\[E(x) = \sum_{i = 1} ^ \infty f(i)
\]
考虑如何求 \(f_i\) 相当于 \(i\) 步前面的 \(gcd\) 一定不为 1
考虑枚举 \(gcd\) 至少为 \(j\) 的然后把它们用容斥原理并起来
\[f(x) = \frac{\sum_{j = 2} ^ m - \mu(j) (\left\lfloor\frac{m}{j}\right\rfloor)^{x - 1}} {m^{x - 1}}
\]
\[E(x) = 1 + \sum_{i = 2} ^ \infty \frac{\sum_{j = 2} ^ m - \mu(j) (\left\lfloor\frac{m}{j}\right\rfloor)^{i - 1}} {m^{i - 1}}
\]
\[= 1 - \sum_{i = 1} ^ \infty \frac{\sum_{j = 2} ^ m \mu(j) (\left\lfloor\frac{m}{j}\right\rfloor)^{i}} {m^{i}}
\]
\[= 1 - \sum_{j = 2} ^ m \mu(j) \sum_{i = 1} ^ \infty (\frac{\left\lfloor\frac{m}{j}\right\rfloor} {m})^i
\]
\[= 1 - \sum_{j = 2} ^ m \mu(j) \frac{(\frac{\left\lfloor\frac{m}{j}\right\rfloor} {m}) ^ \infty - (\frac{\left\lfloor\frac{m}{j}\right\rfloor} {m})} {(\frac{\left\lfloor\frac{m}{j}\right\rfloor} {m}) - 1}
\]
\[= 1 + \sum_{j = 2} ^ m \mu(j) \frac{(\frac{\left\lfloor\frac{m}{j}\right\rfloor} {m})} {(\frac{\left\lfloor\frac{m}{j}\right\rfloor} {m}) - 1}
\]
\[= 1 + \sum_{j = 2} ^ m \mu(j) \frac{\left\lfloor\frac{m}{j}\right\rfloor} {\left\lfloor\frac{m}{j}\right\rfloor - m}
\]
然后就做完了,写个线性求逆元就可以 \(O(m)\) 了
#include <bits/stdc++.h>
using namespace std;
#define gc getchar
#define rg register
#define I inline
#define rep(i, a, b) for(int i = a; i <= b; ++i)
#define per(i, a, b) for(int i = a; i >= b; --i)
I int read(){
rg char ch = gc();
rg int x = 0, f = 0;
while(!isdigit(ch)) f |= (ch == '-'), ch = gc();
while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc();
return f ? -x : x;
}
int n, m;
const int N = 1e5 + 5, mod = 1e9 + 7;
int prime[N], cnt, pre[N], mu[N];
int inv[N];
I void ola(int n){
mu[1] = 1;
rep(i, 2, n){
if(!pre[i]){
prime[++cnt] = i;
pre[i] = i;
mu[i] = -1;
}
for(int j = 1;j <= cnt && prime[j] * i <= n; ++j){
pre[i * prime[j]] = prime[j];
if(prime[j] == pre[i]){
mu[i * prime[j]] = 0;
break;
}
mu[i * prime[j]] = -mu[i];
}
}
}
signed main(){
m = read();
inv[1] = 1;
rep(i, 2, m) inv[i] = ((-mod / i * 1ll * inv[mod % i]) % mod + mod) % mod;
int res = 1;
ola(m);
rep(i, 2, m){
res = (res - 1ll * mu[i] * (m / i) % mod * inv[m - m / i] % mod + mod) % mod;
}
cout << res << endl;
return 0;
}