1. 程式人生 > 實用技巧 >牛牛和牛可樂的賭約

牛牛和牛可樂的賭約

連結:https://ac.nowcoder.com/acm/contest/7412/A
來源:牛客網

牛可樂發明了一種n面骰子(點數分別從11{}1n{}nn,擲出每面的概率為1n\frac {1} {n}n1)去給牛牛玩,因為牛牛是個歐皇,所以他想測試一下牛牛的人品,他告訴牛牛,讓牛牛投mm{}m次骰子,牛牛如果全部投出點數為n{}nn的面就算牛牛贏,牛牛很相信自己的人品,就和牛可樂賭一包辣條,說自己肯定可以全部投出點數為n{}nn點面,但是牛牛又有點害怕自己打賭輸了,想讓你提前幫他計算一下他輸概率有多少?

輸入描述:

有多組輸入樣例,第一行為樣例組數t(t≤1×106)t(t\leq 1×10^6)tt1×106
接下來t行每行有一個整數n和m,分別表示骰子的面數和牛牛的投擲次數

(n,m<=1×109)(n,m<=1×10^9)n,m<=1×109

輸出描述:

輸出t行,每行輸出為分數p/q mod 1e9+7的形式

示例1

輸入

複製
1
2 1

輸出

複製
500000004

備註:

資料較大,建議使用較快的輸入輸出


思路:逆元
有關逆元資訊可以看這個:https://blog.csdn.net/qq_35416331/article/details/81059747
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
ll poww(ll a,ll b,ll mod){
	ll ans=1;
	ll base=a;
	while(b){
		if(b&1)ans=ans*base%mod;
		base=base*base%mod;
		b>>=1;
	}
	return ans%mod;
}
ll inv(ll a,ll mod){
	return poww(a,mod-2,mod);
}
int main()
{
	ll t;
	t=read();
	while(t--)
	{
		ll n,m;
		n=read();
		m=read();
		ll sum=poww(n,m,mod);
		ll ans=((sum-1)*inv(sum,mod))%mod;
		cout<<ans%mod<<endl;
	//	cout<<(n-1)*inv(n,mod)*m<<endl;
	}
	return 0;
}