2019牛客暑期多校训练营(第二场)----A-Eddy Walker

首先发出题目链接:
链接:https://ac.nowcoder.com/acm/contest/882/A
来源:牛客网
涉及:排列组合数学

点击这里回到2019牛客暑期多校训练营解题—目录贴


题目如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
说实话,这次出题人的脑洞真大

题目意思解释一下:有一个环,上面有n个点,分别是从0到n-1
在这里插入图片描述
从0号点出发,然后随意走,每落脚到一个地方就拿起此位置标记(刚开始每个点都有标记),然后求所有点走完后,最后落脚到m点的概率
ps:落脚到一个地方,表示暂时停止移动了,并不是路过一个地方。

注意:题目中还说明了按样例顺序最后落到每个点的概率。
也就是说,比如说样例输入吧,第一次n=1,最后落脚到0号点第二次n=2,最后落脚到1号点,那么第二次落脚到1号点的概率就等于第一次n=1落脚到0号点的概率乘上n=2落脚到1号点的概率。

以此类推,第三次n=3,落脚到0号点的概率等于前两次的概率乘积乘上n=3落脚0号点的概率。


环上有n个点,从0号点出发走遍其他点,一共有 A n − 1 n − 1 A_{n-1}^{n-1} An1n1中可能的顺序,也就是其他n-1个点的排列数。

但是在这 A n − 1 n − 1 A_{n-1}^{n-1} An1n1中情况中,最后落脚点为m的情况有 A n − 2 n − 2 A_{n-2}^{n-2} An2n2,也就是另外n-2个点的排列数

1.如果 n ≥ 1 n\ge 1 n1,从0号点出发,最后落脚点为 m ( m ≠ 0 ) m(m\ne 0) m(m̸=0)的概率为
A n − 2 n − 2 A n − 1 n − 1 = ∏ i = 1 n − 2 i ∏ i = 1 n − 1 i = 1 n − 1        ( n > 1 ) \frac {A_{n-2}^{n-2}}{A_{n-1}^{n-1}}=\frac {\prod_{i=1}^{n-2}i}{\prod_{i=1}^{n-1}i}=\frac 1{n-1}\;\;\;(n> 1) An1n1An2n2=i=1n1ii=1n2i=n11(n>1)

2.如果 n ≥ 1 n\ge 1 n1,从0号点出发,最后落脚点为0号点,那么概率一定为0,因为最后落脚点肯定不是0号点

3.如果 n = 1 , m = 0 n=1,m=0 n=1m=0,从0号点出发,最后落脚点为0号点,概率一定为1,因为只有一个点,最后落脚点肯定是0号点


由于要按照所有场景发生的顺序来输出每个场景发生的概率,所以可以用一个前缀乘积来保存之前所有场景发生的概率,在乘上当前场景的概率,就是当前场景按顺序发生的概率了。

注意还要分数取模用快速幂


举个例子:

输入:
3
4 2
3 1
2 0

首先第一个场景一共4个点,落脚2号点的概率为 1 3 \frac 1{3} 31,所以此场景按顺序发生的概率为 1 3 ∗ 1 = 1 3 \frac 1{3}*1=\frac 1{3} 311=31

第二个场景一共3个点,落脚1号点的概率为 1 2 \frac 1{2} 21,所以此场景按顺序发生的概率为 1 2 ∗ 1 3 = 1 6 \frac 1{2}*\frac 1{3}=\frac 1{6} 2131=61

第三个场景一共2个点,落脚0号点的概率为 0 0 0,所以此场景按顺序发生的概率为 0 ∗ 1 6 = 0 0*\frac 1{6}=0 061=0

所以输出
1 3 \frac 1{3} 31 1 6 \frac 1{6} 61 0 0 0


代码如下:

#include <iostream>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int t,n,m;
ll ans=1; 
ll qpow(ll x){//快速幂求分数取模逆元
	ll pow=mod-2,sum=1;
	while(pow){
		if(pow%2==1)	sum=sum*x%mod;
		pow>>=1;
		x=x*x%mod;
	}
	return sum;
}
int main(){
	cin>>t;
	while(t--){
		scanf("%d%d",&n,&m);
		//下面就是三种情况,注意ans保存前缀乘积
		if(n==1 && m==0)	ans=ans*1;
		else if(m==0)	ans=0;
		else	ans=ans*qpow(n-1)%mod;
		printf("%lld\n",ans);
	}
	return 0;
} 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值