CF838D Airplane Arrangement

题目描述:https://www.luogu.org/problemnew/show/CF838D(有翻译)

(为什么博客园把我刚写的给吞了……orz)

这题当初看的十分懵逼,不过听了肖大佬的做法还是很清楚的。

因为乘客们可以从双向进入,然后乘客只会看给自己安排的座位和后面的空座位,所以我们不如直接新建一个虚拟座位,把这个序列变成一个环。乘客在找不到真实座位中找不到座位了,自然就会坐到虚拟位置上。因此,如果一个方案中虚拟位置被坐了说明不合法,否则就合法。

虚拟位置与其他位置一样是一个普通的座位,对于m个人来说,其没有被占据的概率为(n+1-m) / (n+1)。而所有的安排数是(2*(n+1)) ^ m,他们的乘积整理出来就是结果,即2^m * (n+1) ^ (m-1) * (n+1-m)

代码很短。(数学题大都难想……不过代码却可能很短)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('
')
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int M = 300005;
ll read()
{
    ll ans = 0,op = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') op = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
    }
    return ans * op;
}

ll n,m;
ll qpow(ll a,ll b)
{
    ll q = 1;
    while(b)
    {
        if(b&1) q *= a,q %= mod;
        a *= a,a %= mod;
        b >>= 1;
    }
    return q;
}
int main()
{
    n = read(),m = read();
    printf("%lld
",qpow(2,m) * qpow(n+1,m-1) % mod * (n+1-m) % mod);
    return 0;
}
原文地址:https://www.cnblogs.com/captain1/p/9434310.html