2019牛客暑期多校訓練營(第二場)----A-Eddy Walker

首先發出題目鏈接:
鏈接:https://ac.nowcoder.com/acm/contest/882/A
來源:牛客網
涉及:排列組合數學

點擊這裏回到2019牛客暑期多校訓練營解題—目錄貼


題目如下:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
說實話,這次出題人的腦洞真大

題目意思解釋一下:有一個環,上面有n個點,分別是從0到n-1
在這裏插入圖片描述
從0號點出發,然後隨意走,每走到一個地方就拿起此位置標記(剛開始每個點都有標記),然後求所有點走完後,最後落腳到m點的概率

注意:題目中還說明了按樣例順序最後落到每個點的概率。
也就是說,比如說樣例輸入吧,第一次n=1,最後落腳到0號點第二次n=2,最後落腳到1號點,那麼第二次落腳到1號點的概率就等於第一次n=1落腳到0號點的概率乘上n=2落腳到1號點的概率。

以此類推,第三次n=3,落腳到0號點的概率等於前兩次的概率乘積乘上n=3落腳0號點的概率。


環上有n個點,從0號點出發走遍其他點,一共有An1n1A_{n-1}^{n-1}中可能的順序,也就是其他n-1個點的排列數。

但是在這An1n1A_{n-1}^{n-1}中情況中,最後落腳點爲m的情況有An2n2A_{n-2}^{n-2},也就是另外n-2個點的排列數

1.如果n1n\ge 1,從0號點出發,最後落腳點爲m(m0)m(m\ne 0)的概率爲
An2n2An1n1=i=1n2ii=1n1i=1n1      (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)

2.如果n1n\ge 1,從0號點出發,最後落腳點爲0號點,那麼概率一定爲0,因爲最後落腳點肯定不是0號點

3.如果n=1m=0n=1,m=0,從0號點出發,最後落腳點爲0號點,概率一定爲1,因爲只有一個點,最後落腳點肯定是0號點


由於要按照所有場景發生的順序來輸出每個場景發生的概率,所以可以用一個前綴乘積來保存之前所有場景發生的概率,在乘上當前場景的概率,就是當前場景按順序發生的概率了。

注意還要分數取模用快速冪


舉個例子:

輸入:
3
4 2
3 1
2 0

首先第一個場景一共4個點,落腳2號點的概率爲13\frac 1{3},所以此場景按順序發生的概率爲131=13\frac 1{3}*1=\frac 1{3}

第二個場景一共3個點,落腳1號點的概率爲12\frac 1{2},所以此場景按順序發生的概率爲1213=16\frac 1{2}*\frac 1{3}=\frac 1{6}

第三個場景一共2個點,落腳0號點的概率爲00,所以此場景按順序發生的概率爲016=00*\frac 1{6}=0

所以輸出
13\frac 1{3} 16\frac 1{6} 00


代碼如下:

#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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章