题意:房间内有 个座位排成一列,有 个人依次进入房间选座位。每个人会有一个目标座位(可以有两人选择同个目标座位),然后选择从前门进入或者后门进入房间,进入房间后会先走到自己的目标座位,如果目标座位已经有人就会继续往前走,直到第一个空位,然后坐下。如果走到房间尽头还没有找到座位,这个人就会生气。求有多少种方案能让所有人都不生气,两个方案不同当且仅当某个人的目标座位不同或进入房间走的门不同。方案数对 取模。
数据范围与约定:。
解析:一道很仙的题,有个巧妙的思路。
我们不考虑进入房间走的哪扇门,因为它只与行走的方向有关。所以题目等价于每个人从其目标位置开始按照既定方向走动即可。
我们可以想象每个人都在一个 的环上顺时针或者逆时针行走,直到找到空位置坐下,但是这样无法表示非法的情况,即乘客生气的情况。我们考虑在 与 的接口处增加一个位置 ,如果这个位置被占据了,那么即可说明状态非法,即有人生气的情况。这很容易理解,如果存在某人在题目中从某个位置走到了房间尽头,那么就是不合法的,在环上走就相当于走到 和 的后一个位置,即 。因此如果 号位置被占据,则必然有人生气,这与题目中的情况是一一映射的。
那么每个人的目标位置有 种,方向有 种,所以每个人有 种选择,所以总方案数是 ,由于环上每个位置都是等价的,所以一个位置被占据的概率为 ,那么 号位置不被占据的概率为 ,所以答案即为 。
/*
* @Author: clorf
* @Date: 2021-02-16 22:19:51
* @Last Modified by: clorf
* @Last Modified time: 2021-02-16 22:34:35
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<ctime>
#include<cctype>
#define INF 2e9
#define rg register
using namespace std;
const int mod=1e9+7;
const int maxn=1000000;
const long double Pi=acos(-1.0);
const double eps=1e-7;
//1.数组开小
//2.没用long long/爆了类型存储范围
//3.写之前式子没推清楚
//4.变量写错(想当然typo/没想清楚含义)
//5.写之前没想清楚复杂度
//6.常量数字与long long连用时要加ll!!!
//7.考虑无解和多解的情况
//8.两个int连成爆long long的一定要加1ll!!!!
//9.先除后乘!!!!!!
template<class T>void read(T &x)
{
x=0;int f=0;char ch=getchar();
while(!isdigit(ch)){f|=(ch=='-');ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return;
}
int n,m,ans;
inline int power(int a,int b,int p)
{
int ans=1;
for(;b;b>>=1)
{
if(b&1)
ans=1ll*ans*a%p;
a=1ll*a*a%p;
}
return ans;
}
inline int inv(int x)
{
return power(x,mod-2,mod);
}
int main()
{
scanf("%d%d",&n,&m);
printf("%d",1ll*(n+1+mod-m)%mod*inv(n+1)%mod*power((n+1)<<1,m,mod)%mod);
return 0;
}