HDU 5793 A Boring Question(快速幂&求逆元)

来源:互联网 发布:boxers知乎 编辑:程序博客网 时间:2024/05/22 15:05

这道题就是给你一个公式,然后再给数据范围给你,然后求答案。

这道题的公式推到最后就是一个等比数列的求和公式,也就是说,输入n和m,然后从m的0次方一直加到n次方的和就是答案。

但是由于这道题的数据太大了,有1e9,所以我们不可能用for循环一直加到最后,所以根据公式,我们需要用到快速幂来求m^n。用快速幂求出来之后,我们根据等比数列的求和公式,就成了(1-m^n)/(1-m)%mod。因为还要对1e9+7取模,所以mod=1e9+7。但是因为要取模,所以直接当做除法来做会出错,所以,要把(1-m)和mod的逆元求出来,当做乘法来做。所以求逆元,其实就是求倒数。所以(1-m)和mod就是其倒数。

#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <cmath>#include <vector>#include <set>#include <list>#include <queue>#include <map>#include <stack>#include <ctime>using namespace std;const int mod=1e9+7;const int maxn = 1000010;long long n,m;long long X,Y;long long mi(long long x,long long a,int p){    long long ans = 1;    x = x % p;    while(a)    {        if(a&1)            ans = (ans * x) % p;        x = (x * x) % p;        a >>= 1;    }    return ans;}long long gcd(long long a,long long b){    int t,d;    if(b == 0)    {        X = 1;        Y = 0;        return a;    }    d = gcd(b,a%b);    t = X;    X = Y;    Y = t - (a / b) * Y;    return d;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%lld%lld",&n,&m);        gcd(m-1,mod);        if(X < 0)            X += mod;        long long ans = (mi(m,n+1,mod)-1)*X%mod;        printf("%lld\n",ans);    }    return 0;}


0 0
原创粉丝点击