CF838D Airplane Arrangements 题解

题意

一架飞机有 \(n\) 个座位排成一列,有 \(m\) 名乘客(\(m \leq n\))依次上飞机。

乘客会选择一个目标座位(两人可以选同一个目标座位),然后选择从前门或者后门上飞机,上飞机后,他们会走到自己的目标座位,如果目标座位已经有人坐了,他们会继续往前走,在走到第一个空位后坐下。如果走到最后还没有找到座位,这名乘客就会生气。

问有多少种登机方案能让所有乘客都不生气。两个登机方案不同当且仅当第 \(i\) 位乘客的目标座位或上飞机走的门不同。

\(1 \le n,m \le 10^6\))。

题解

将座位 \(1\) 和座位 \(n\) 中间插入一个座位 \(n + 1\) 并相连,使其成为一个环。计算合法的概率。可以发现一个方案不合法当且仅当有人坐到座位 \(n + 1\) 上。

现在问题转化为了有一个长度为 \(n + 1\) 的环,乘客会从前 \(n\) 个位置出现,往一个方向行走,直到有空位后坐下,问第 \(n + 1\) 个位置没有人坐下的概率。其中第 \(n + 1\) 个位置是特殊的导致了很难计算,发现如果有乘客在第 \(n + 1\) 个位置出现,那么第 \(n + 1\) 个位置上在他选定座位后一定有人,所以一定会被计算为不合法,故乘客可以在第 \(n + 1\) 个位置上出现。

那么现在的 \(n + 1\) 个位置已经等价,所以在有 \(m\) 个人坐下的情况下第 \(n + 1\) 个位置上有人的概率即为 \(\dfrac{m}{n + 1}\)。再乘上总的方案数 \(\left(2 \times \left(n + 1\right)^m\right)\) 即可得出最终答案。

Code

#include <bits/stdc++.h>

typedef long long valueType;

constexpr valueType MOD = 1e9 + 7;

template<typename T1, typename T2, typename T3 = valueType>
T1 mul(T1 a, T2 b, const T3 &mod = MOD) {
    return (long long) a * b % mod;
}

template<typename T1, typename T2, typename T3 = valueType>
void Mul(T1 &a, T2 b, const T3 &mod = MOD) {
    a = (long long) a * b % mod;
}

template<typename T1, typename T2, typename T3 = valueType>
T1 pow(T1 a, T2 b, const T3 &mod = MOD) {
    T1 result = 1;

    while (b > 0) {
        if (b & 1)
            Mul(result, a, mod);

        Mul(a, a, mod);
        b = b >> 1;
    }

    return result;
}

int main() {
    valueType N, M;

    std::cin >> N >> M;

    valueType const ans = mul(mul(N + 1 - M, pow(N + 1, MOD - 2)), pow(2 * (N + 1), M));

    std::cout << ans << std::endl;
}
posted @ 2023-09-03 20:43  User-Unauthorized  阅读(10)  评论(0编辑  收藏  举报