牛牛和牛可乐的赌约

链接: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<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long ll;
const int N = 1e9+7;
ll read() {  //快读
    char ch = getchar();
    int x = 0,y = 1;
    while(ch < '0'|| ch > '9') {
        if(ch == '-') {
            y = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        x = x*10 + ch - '0';
        ch = getchar();
    }
    return x*y;
}
ll k(ll a,ll b,ll mod){
    ll t = 1;
    while(b) {
        while(b%2 != 0) {
            t = (a*t)%mod;
            b--;
        }
        a = (a*a)%mod;
        b /= 2;
    }
    return t;
}
ll inv(ll a,ll mod) {
    return k(a,mod-2,mod);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        ll n,m;
        n = read();
        m = read();
        ll sum = k(n,m,N);
        ll ans = ((sum-1)*inv(sum,N))%N;
        cout<<ans%N<<endl; 
    }
    return 0;

  

posted @ 2020-09-21 16:53  陈墨cacm  阅读(225)  评论(0编辑  收藏  举报