[概率,期望]CF1523E Crypto Lights

\(\texttt{link}\)

\(p_i\) 为点亮 \(i\) 栈灯后停止的概率,则有:

\[E = \sum\limits_{i=1}^n ip_i \]

\(p\) 做一个后缀和,记 \(s_i = \sum\limits_{j=i}^np_j\),则有:

\[E = \sum\limits_{i=1}^n s_i \]

在这里,\(s_i\) 可以看作是点亮 \(i-1\) 栈灯并且没有停止的概率,考虑怎么计算这个 \(s_i\)

点亮 \(i - 1\) 盏灯的总方案数为 \(\dbinom{n}{i-1}\),这里包含不合法的;

合法的方案中,相邻的两盏灯之间至少有 \(k-1\) 栈灯,则合法的方案数为 \(\dbinom{n-(k-1)*(i-2)}{i-1}\)

于是有

\[s_i = \dfrac{\dbinom{n-(k-1)*(i-2)}{i-1}}{\dbinom n {i-1}} \]

\[E = \sum\limits_{i=1}^n \frac{\dbinom{n-(k-1)*(i-2)}{i-1}}{\dbinom n {i-1}} \]

特判 \(i=1\)

\(\texttt{Code:}\)

#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define mp make_pair
#define fi first
#define se second

using namespace std;

inline void read(int &x) {
    x = 0; int f = 0; char c = getchar();
    while (!isdigit(c)) f |= c == '-', c = getchar();
    while (isdigit(c)) x = x * 10 + (c ^ 48), c = getchar();
    x = f ? -x : x;
}

const int cmd = 1e9 + 7;
const int N = 2e5 + 5;

int fpow(int a, int b) {
    int res = 1;
    for (; b; b >>= 1, a = 1ll * a * a % cmd)
        if (b & 1) res = 1ll * res * a % cmd;
    return res;
}

int n, k, fac[N], ifac[N];

int C(int n, int m) {
    return n < m ? 0 : 1ll * fac[n] * ifac[m] % cmd * ifac[n - m] % cmd;
}

int main() {
    int T; read(T);
    fac[0] = ifac[0] = 1;
    for (int i = 1; i <= 100000; i++) {
        fac[i] = 1ll * fac[i - 1] * i % cmd;
        ifac[i] = fpow(fac[i], cmd - 2);
    }
    while (T--) {
        read(n); read(k);
        int ans = 1;
        for (int i = 2; i <= n; i++) {
            if ((k - 1) * (i - 2) > n) break;
            ans = (ans + 1ll * C(n - (k - 1) * (i - 2), i - 1) * fpow(C(n, i - 1), cmd - 2)) % cmd;
        }
        printf("%d\n", ans);
    }
    return 0;
}
posted @ 2021-11-15 09:58  klii  阅读(52)  评论(0)    收藏  举报