牛客挑战赛B随机数 (费马小定理+对大数的取模+组合数学出现次数为奇数的问题)

链接: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的个数为奇数的概率。为避免误差,答案对10 9+7取模(设答案化为的最简分数为 ,则输出A· B -1 mod (10 9+7),其中B -1是B模10 9+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;
}

  



猜你喜欢

转载自www.cnblogs.com/vainglory/p/9218747.html
今日推荐