1. 程式人生 > >牛客挑戰賽B隨機數 (費馬小定理+對大數的取模+組合數學出現次數為奇數的問題)

牛客挑戰賽B隨機數 (費馬小定理+對大數的取模+組合數學出現次數為奇數的問題)

IT pre 運行 tps long 時間 DC 之間 typedef

鏈接:https://www.nowcoder.com/acm/contest/129/B
來源:牛客網

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld

題目描述

有一個隨機數生成器,每次運行以a/10000的概率產生1,1-a/10000的概率產生0,兩次運行之間相互獨立。
求運行n次後,產生1的個數為奇數的概率。為避免誤差,答案對109+7取模(設答案化為的最簡分數為技術分享圖片,則輸出A· B-1 mod (109+7),其中B-1是B模109+7的乘法逆元)。

輸入描述:

第一行一個整數,表示a
第二行一個整數,表示n

輸出描述:

一個整數,表示答案
示例1

輸入

復制
2500
3

輸出

復制
937500007

備註:

技術分享圖片

0≤ a ≤ 10000


首先給出費馬小定理::: 如果p是質數且gcd(p,a)==1>>則a^(p-1)%p==1>>>針對a^n取模的運算
其次::講述取模的條件>>交換律與結合律>>這一部分我沒有系統的學習過>>不好說>>只能積累經驗
再其次>>講述>>假設一枚硬幣正面向上的概率是p,求拋n次>>奇數次向上的概率



技術分享圖片
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll pow_(ll a,ll b){
	ll res=1,tmp=a;
	while(b){
		if(b&1) (res*=tmp)%=mod;
		(tmp*=tmp)%=mod;
		b/=2;
	}
	return res;
}
int main(){
	std::ios::sync_with_stdio(false);
	string s;int a;cin>>a>>s;ll n=0;
	for(int i=0;i<s.size();i++)
		n=(n*10+s[i]-‘0‘)%(mod-1);
	ll p=a*pow_(10000,mod-2);
	p=1-2*p;
	p=(p%mod+mod)%mod;
	ll ans=1-pow_(p,n);
	ans=(ans%mod+mod)%mod;
	ans*=(mod+1)/2;ans%=mod;
	cout<<ans<<endl;
	return 0;
}

  



牛客挑戰賽B隨機數 (費馬小定理+對大數的取模+組合數學出現次數為奇數的問題)