CF1139D Steps to One 题解

一道莫反好题。

先证个式子:\(E(X)=\sum_{i\ge 1}P(X \ge i)\),也就是最终长度为 \(X\) 的期望是所有最终长度小于等于 \(X\) 的概率之和。

证明:\(E(X)=\sum_{i\ge 1}iP(X=i)=\sum_{i\ge 1}\sum_{1\le j\le i}P(X=i)=\sum_{j\ge 1}\sum_{i\ge j}P(X=i)=\sum_{j\ge1}P(x\ge j)\)

考虑容斥,最终长度大于等于 \(i\) 等价于长度为 \(i-1\) 的序列 \(\gcd\) 大于 1,这个可以用 1 减去 \(\gcd=1\) 的概率,注意这里的 \(i \ge 2\)

概率用满足条件方案数 / 总方案数计算,总方案数 \(m^{i-1}\),因此只需要计算 \(i-1\)\(\gcd=1\) 的方案数即可。

\(\gcd=1\) 的式子:\(\sum_{1 \le a_1,a_2,...,a_{i-1} \le m}[\gcd(a_1,a_2,...,a_{i-1})=1]\)

莫比乌斯反演,得到 \(\sum_{1 \le a_1,a_2,...,a_{i-1}\le m}\sum_{d \mid \gcd(a_1,a_2,...,a_{i-1})}\mu(d)\)

换个枚举顺序,顺便处理一下求和符号得到 \(\sum_{d=1}^{m}\mu(d)\lfloor\dfrac{m}{d}\rfloor^{i-1}\)

然后开始计算答案式子,为 \(1+\sum_{i\ge2}\dfrac{m^{i-1}-\sum_{d=1}^m\mu(d)\lfloor\dfrac{m}{d}\rfloor^{i-1}}{m^{i-1}}\)

\(i-1\) 太丑,令 \(i \gets i-1\),得到 \(1+\sum_{i\ge1}\dfrac{m^i-\sum_{d=1}^m\mu(d)\lfloor\dfrac{m}{d}\rfloor^i}{m^i}\)

注意到 \(d=1\)\(\sum_{d=1}^{m}\mu(d)\lfloor\dfrac{m}{d}\rfloor^i=m^i\),因此将这一部分提出来与 \(m^i\) 消掉。

然后交换求和符号,得到 \(1-\sum_{d=1}^{m}\mu(d)(\dfrac{\lfloor\frac{m}{d}\rfloor}{m})^i\)

因为 \(\dfrac{\lfloor\frac{m}{d}\rfloor}{m}<1\),根据 \(x<1 \to \sum_{i\ge1}x^i=\dfrac{x}{1-x}\)(貌似是用生成函数推的),得到 \(1-\sum_{d=1}^{m}\mu(d)\dfrac{\dfrac{\lfloor\frac{m}{d}\rfloor}{m}}{m-\dfrac{\lfloor\frac{m}{d}\rfloor}{m}}\),然后整除分块即可。

GitHub:CodeBase-of-Plozia

Code:

/*
========= Plozia =========
	Author:Plozia
	Problem:CF1139D Steps to One
	Date:2022/3/1
========= Plozia =========
*/

#include <bits/stdc++.h>

typedef long long LL;
const int MAXN = 1e5 + 5;
const LL P = 1e9 + 7;
int t, n, cntPrime, Prime[MAXN];
LL mu[MAXN], inv[MAXN];
bool book[MAXN];

int Read()
{
	int sum = 0, fh = 1; char ch = getchar();
	for (; ch < '0' || ch > '9'; ch = getchar()) fh -= (ch == '-') << 1;
	for (; ch >= '0' && ch <= '9'; ch = getchar()) sum = sum * 10 + (ch ^ 48);
	return sum * fh;
}
int Max(int fir, int sec) { return (fir > sec) ? fir : sec; }
int Min(int fir, int sec) { return (fir < sec) ? fir : sec; }
LL ksm(LL a, LL b = P - 2, LL p = P)
{
	LL s = 1 % p;
	for (; b; b >>= 1, a = a * a % p)
		if (b & 1) s = s * a % p;
	return s;
}

void init()
{
	book[1] = mu[1] = 1;
	for (int i = 2; i <= n; ++i)
	{
		if (!book[i]) { Prime[++cntPrime] = i; mu[i] = -1; }
		for (int j = 1; j <= cntPrime; ++j)
		{
			if (i * Prime[j] > n) break ;
			book[i * Prime[j]] = 1;
			if(i % Prime[j] == 0) { mu[i * Prime[j]] = 0; break ; }
			mu[i * Prime[j]] = -mu[i];
		}
	}
	for (int i = 2; i <= n; ++i) mu[i] = mu[i - 1] + mu[i];
}

int main()
{
	n = Read(); init(); LL ans = 0;
	for (int i = 1; i <= n; ++i) inv[i] = ksm(i);
	for (int l = 2, r; l <= n; l = r + 1)
	{
		r = Min(n / (n / l), n);
		ans = (ans + (mu[r] - mu[l - 1]) * (n / l) % P * inv[n - (n / l)] % P) % P;
	}
	ans = ((1 - ans) % P + P) % P;
	printf("%lld\n", ans);
	return 0;
}
posted @ 2022-04-17 19:01  Plozia  阅读(44)  评论(0编辑  收藏  举报