CF838D Airplane Arrangements

传送门:https://www.luogu.org/problemnew/show/CF838D

 

这道题反正我自己想是毫无头绪,最后还是听了肖大佬的做法。

因为题中说乘客可以从前后门进来,所以我们可以把这n个作为想象成一个环,然后乘客们都从n + 1的位置出发,于是从前后门就变成了顺逆时针。

很容易得出,所有方案为 [2 * (n +1)] ^ m 种,但是这其中包含了不合法方案,所以要减去不合法的情况。那么什么是不合法的情况呢?一个人转了一圈又回到了 n + 1 号的座位,就说明他没有找到位置,所以所有不合法的情况就是走到n + 1的情况。

然后因为每一个座位是一样的,所以走到的合法情况的概率是等价的,都是 (n +1 - m) / (n + 1),所以最终的答案就是 [2 * (n +1)] ^ m * (n +1 - m) / (n + 1)。

化简一下:     2 ^ m * (n +1) ^ (m - 1) * (n +1 - m)

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<stack>
 9 #include<queue>
10 #include<vector>
11 using namespace std;
12 #define enter printf("\n")
13 #define space printf(" ")
14 #define Mem(a) memset(a, 0, sizeof(a))
15 typedef long long ll;
16 typedef double db;
17 const int INF = 0x3f3f3f3f;
18 const db eps = 1e-8;
19 const int maxn = 6e5 + 5;
20 const ll mod = 1e9 + 7;
21 inline ll read()
22 {
23     ll ans = 0;
24     char ch = getchar(), last = ' ';
25     while(!isdigit(ch)) {last = ch; ch = getchar();}
26     while(isdigit(ch))
27     {
28         ans = ans * 10 + ch - '0'; ch = getchar();
29     }
30     if(last == '-') ans = -ans;
31     return ans;
32 }
33 inline void write(ll x)
34 {
35     if(x < 0) x = -x, putchar('-');
36     if(x >= 10) write(x / 10);
37     putchar(x % 10 + '0');
38 }
39 
40 ll n, m;
41 
42 ll quickpow(ll a, ll b)
43 {
44     a %= mod;
45     ll ret = 1;
46     while(b)
47     {
48         if(b & 1) ret = ret * a % mod;
49         a = a * a % mod; b >>= 1;
50     }
51     return ret;
52 }
53 
54 int main()
55 {
56     n = read(); m = read();
57     write(quickpow((ll)2, m) * quickpow(n + 1, m - 1) % mod * (n + 1 - m) % mod); enter;
58     return 0;
59 }

 

posted @ 2018-08-06 10:58  mrclr  阅读(1315)  评论(0编辑  收藏  举报