Loading

【题解】CF1139D Steps to One

不太会期望题,记一下有用的想法。

思路

期望 + 莫反。

\(E(l)\) 为序列长度的期望,\(P(x)\) 为事件 \(x\) 发生的概率。

首先根据期望的定义有 \(E(l) = \sum\limits_{i \geq 1} P(l = i) \cdot i\)

等价于 \(E(l) = \sum\limits_{i \geq 1} P(l = i) \sum\limits_{j = 1}^i\)

\(E(l) = \sum\limits_{j \geq 1} \sum\limits_{i \geq j} P(l = i)\)

根据定义得 \(E(l) = \sum\limits_{i \geq 1} P(l \geq i) = 1 + \sum\limits_{i \geq 1} P(l > i)\)

考虑求出 \(P(l > i)\).

根据 \(P(l = i)\) 的定义知 \(P(l = i) = \frac{\sum\limits_{a_1 = 1}^m \cdots \sum\limits_{a_i = 1}^m [\gcd(a_1, \cdots, a_i) = 1]}{m^i}\)

所以 \(P(l > i) = \frac{\sum\limits_{a_1 = 1}^m \cdots \sum\limits_{a_i = 1}^m [\gcd(a_1, \cdots, a_i) > 1]}{m^i}\)

因为 \(\gcd(a_1, \cdots, a_i) \geq 1\),所以 \(P(\gcd(a_1, \cdots, a_i) > 1) = 1 - P(\gcd(a_1, \cdots, a_i) = 1)\)

所以 \(P(l > i) = 1 - \frac{\sum\limits_{a_1 = 1}^m \cdots \sum\limits_{a_i = 1}^m [\gcd(a_1, \cdots, a_i) = 1]}{m^i}\)

根据 \(\mu\) 的性质知 \(P(l > i) = 1 - \frac{\sum\limits_{a_1 = 1}^m \cdots \sum\limits_{a_i = 1}^m \sum\limits_{d \mid \gcd(a_1, \cdots, a_i)} \mu(d)}{m^i}\)

根据莫反套路可以推导出:\(P(l > i) = 1 - \frac{\sum\limits_{d = 1}^m \mu(d) \cdot (\lfloor \frac{m}{d} \rfloor)^i}{m^i}\)

因为 \(d = 1\) 时后一项的值等于 \(-1\),所以可以抵消:

\(P(l > i) = -\frac{\sum\limits_{d = 2}^m \mu(d) \cdot (\lfloor \frac{m}{d} \rfloor)^i}{m^i}\)

\(P(l > i)\) 代入回 \(E(l)\)

\(E(l) = 1 + \sum\limits_{i \geq 1} P(l > i) = 1 - \sum\limits_{i \geq 1} \frac{\sum\limits_{d = 2}^m \mu(d) \cdot (\lfloor \frac{m}{d} \rfloor)^i}{m^i}\)

整理可得 \(E(l) = 1 - \sum\limits_{d = 2}^m \sum\limits_{i \geq 1} \mu(d) \cdot (\frac{\lfloor \frac{m}{d} \rfloor}{m})^i\)

根据等比数列求和公式可以继续化简:

\(E(l) = 1 - \sum\limits_{d = 2}^m \mu(d) \cdot \frac{\lfloor \frac{m}{d} \rfloor}{m - \lfloor \frac{m}{d} \rfloor}\)

然后直接筛出 \(\mu\) 求值就行,时间复杂度 \(O(m \log V)\)

代码

#include <cstdio>
#include <vector>
#include <bitset>
using namespace std;

const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;

int n;
int mu[maxn];
vector<int> p;
bitset<maxn> vis;

int qpow(int base, int power)
{
    int res = 1;
    while (power)
    {
        if (power & 1) res = 1ll * res * base % mod;
        base = 1ll * base * base % mod;
        power >>= 1;
    }
    return res;
}

void init()
{
    mu[1] = 1, vis[1] = true;
    for (int i = 2; i <= n; i++)
    {
        if (!vis[i]) p.push_back(i), mu[i] = -1;
        for (int j = 0; (j < p.size()) && (i * p[j] <= n); j++)
        {
            vis[i * p[j]] = true;
            if (i % p[j] == 0) { mu[i * p[j]] = 0; break; }
            else mu[i * p[j]] = -mu[i];
        }
    }
}

int main()
{
    scanf("%d", &n);
    init();
    int ans = 1;
    for (int i = 2; i <= n; i++) ans = (ans - 1ll * mu[i] * (n / i) % mod * qpow(n - n / i, mod - 2) % mod + mod) % mod;
    printf("%d\n", ans);
    return 0;
}
posted @ 2023-01-19 10:46  kymru  阅读(15)  评论(0编辑  收藏  举报