CodeForces - 838D Airplane Arrangements
作者:互联网
目录
题目
解法
自闭了。
我们将飞机变成 \(\mathtt{UFO}\),前后门就连在一起合成一个点 \(n+1\)。这就是长度为 \(n+1\) 的环,前后门就变成了顺逆时针。需要注意的是,\(n+1\) 与其它点完全一样,所以到了 \(n+1\) 如果已占就会沿先前方向继续走。
从 每个人的目标座位和前后门 来分析总方案数:\((2\times (n+1))^m\)。
如何删掉不合法的方案?因为用登机方案来判断最终座位以及是否合法非常麻烦,我们另辟蹊径。首先我们知道,坐了 \(n+1\) 这个位置就不合法(注意这不是目标态而是最终态)。在分析总方案数时,我们将所有的点视作同样的,而且到了 \(n+1\) 如果已占就会沿先前方向继续走,感性可得所有座位被坐的概率相同。又因为一共坐 \(m\) 个座位,设每个座位被坐的概率为 \(p\),有 \(p\times (n+1)=m\),则 \(p=\frac{m}{n+1}\)。那么每个座位不被坐的概率为 \(\frac{n+1-m}{n+1}\)。
所以答案就是 \((2\times (n+1))^m\times \frac{n+1-m}{n+1}\)。
最后分析一下一种看似会被多算的情况:目标位置为 \(n+1\)。这样最终 \(n+1\) 一定会被坐,所以又被减去了。
代码
#include <cstdio>
#define rep(i,_l,_r) for(register signed i=(_l),_end=(_r);i<=_end;++i)
#define fep(i,_l,_r) for(register signed i=(_l),_end=(_r);i>=_end;--i)
#define erep(i,u) for(signed i=head[u],v=to[i];i;i=nxt[i],v=to[i])
#define efep(i,u) for(signed i=Head[u],v=to[i];i;i=nxt[i],v=to[i])
#define print(x,y) write(x),putchar(y)
template <class T> inline T read(const T sample) {
T x=0; int f=1; char s;
while((s=getchar())>'9'||s<'0') if(s=='-') f=-1;
while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
return x*f;
}
template <class T> inline void write(const T x) {
if(x<0) return (void) (putchar('-'),write(-x));
if(x>9) write(x/10);
putchar(x%10^48);
}
template <class T> inline T Max(const T x,const T y) {if(x>y) return x; return y;}
template <class T> inline T Min(const T x,const T y) {if(x<y) return x; return y;}
template <class T> inline T fab(const T x) {return x>0?x:-x;}
template <class T> inline T gcd(const T x,const T y) {return y?gcd(y,x%y):x;}
template <class T> inline T lcm(const T x,const T y) {return x/gcd(x,y)*y;}
const int mod=1e9+7;
int qkpow(int x,int y) {
int r=1;
while(y) {
if(y&1) r=1ll*r*x%mod;
x=1ll*x*x%mod; y>>=1;
}
return r;
}
int main() {
int n=read(9),m=read(9);
print(1ll*qkpow(2*(n+1),m)*(n+1-m)%mod*qkpow(n+1,mod-2)%mod,'\n');
return 0;
}
标签:return,int,CodeForces,template,inline,const,Airplane,838D,mod 来源: https://www.cnblogs.com/AWhiteWall/p/14404307.html