n n n 个位置排成一排,有 m m m 个人依次进场选位置
每个人开始会选择一个方向(从左至右或从右至左)并选择一个位置。他会走到他选择的那个位置,如果那个位置被人占用了,他会沿着他选择的方向一路走到第一个空位并坐下。
求有多少种情况满足每个人都有座位。
1 ≤ m ≤ n ≤ 1 0 6 1\le m \le n\le 10^6 1 ≤ m ≤ n ≤ 1 0 6
Links CF838D
Solution 新加入一个n + 1 n+1 n + 1 号点,把所有点看成一个环
每个人从选择的位置开始,往顺时针/逆时针走,找到第一个空座位就坐下
一旦n + 1 n+1 n + 1 这个点被占据,就说明有人找不到座位,所以题目转化为求n + 1 n+1 n + 1 这个点没被占据的方案数
原题中总方案数是( 2 n ) m (2n)^m ( 2 n ) m 的,但在这里我们假设每个人都有可能从n + 1 n+1 n + 1 出发,即总方案数为( 2 n + 2 ) m (2n+2)^m ( 2 n + 2 ) m ,这样就能保证每个点是等价的,且对答案不会产生影响(从n + 1 n+1 n + 1 出发的答案都是不合法的)
所以每个点被占据的概率相同,均为m n + 1 \frac{m}{n+1} n + 1 m
因此n + 1 n+1 n + 1 这个点没有被占据的概率就是n + 1 − m n + 1 \frac{n+1-m}{n+1} n + 1 n + 1 − m
答案即为总方案数乘概率
Summary 在所有点等价的情况下,如果某个东西的方案数不好算,可以考虑用总方案数乘上这个时间发生的概率
Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #include <bits/stdc++.h> #define x first #define y second #define y1 Y1 #define y2 Y2 #define mp make_pair #define pb push_back using namespace std ;typedef long long LL;typedef pair<int , int > pii;template <typename T> inline int Chkmax (T &a, T b) { return a < b ? a = b, 1 : 0 ; }template <typename T> inline int Chkmin (T &a, T b) { return a > b ? a = b, 1 : 0 ; }inline void proc_status () { ifstream t ("/proc/self/status" ) ; cerr << string (istreambuf_iterator <char > (t), istreambuf_iterator <char > ()) <<endl ; } template <typename T> T read () { T sum = 0 , fl = 1 ; char ch = getchar(); for (; !isdigit (ch); ch = getchar()) if (ch == '-' ) fl = -1 ; for (; isdigit (ch); ch = getchar()) sum = (sum << 3 ) + (sum << 1 ) + ch - '0' ; return sum * fl; } const int Maxn = 1000000 + 100 , Mod = 1e9 + 7 ;int N, M;inline int Pow (int a, int b) { int ans = 1 ; for (int i = b; i; i >>= 1 , a = 1l l * a * a % Mod) if (i & 1 ) ans = 1l l * ans * a % Mod; return ans; } inline void Solve () { printf ("%lld\n" , 1l l * Pow((2l l * N + 2 ) % Mod, M) * (N + 1 - M) % Mod * Pow(N + 1 , Mod - 2 ) % Mod); } inline void Input () { N = read<int >(), M = read<int >(); } int main () {#ifndef ONLINE_JUDGE freopen("D.in" , "r" , stdin ); freopen("D.out" , "w" , stdout ); #endif Input(); Solve(); return 0 ; }