UVA_live 7720 思考 数论 快速幂取模

来源:互联网 发布:太行航空发动机知乎 编辑:程序博客网 时间:2024/06/05 20:51

题目大意:


仔细思考,分析下例子,会发现这是一个等比数列求和的问题。第n-1项求和之后做第n-2项的首项然后再求和一直求到第0项。

但是这题有个坑,就是取模时,除数要转换成它的逆元,然后整个式子变成乘法,就可以直接去模了。

因为1e9+7是质数,所以可以通过费马小定理求出一个数的逆元。。。

代码:

#include<bits/stdc++.h>#include<math.h>using namespace std;#define ll long long#define M(a,b) memset(a,b,sizeof(a))const ll mod=1e9+7;struct ssr{    ll a;    ll b;    ll c;} num[105];ll qpow(ll  a,ll b){    ll ans=1;    if(a==0)    {        return 0;    }    else    {        while(b)        {            if(b&1)ans=(a%mod)*(ans%mod);            b>>=1;            a=(a%mod)*(a%mod);        }    }    return ans%mod;}ll inv(ll a)//费马小定理求逆元{    return qpow(a,mod-2);}int main(){    int t,cas;    while(~scanf("%d",&t))    {        cas=1;        while(t--)        {            int n;            scanf("%d",&n);            for(int i=0; i<n; i++)            {                scanf("%lld %lld %lld",&num[i].a,&num[i].b,&num[i].c);            }            ll sum=1;            for(int i=0; i<n; i++)            {                sum=(sum%mod*qpow(num[i].a,num[i].b)%mod)%mod;            }            if(num[n-1].a==1)            {                sum=(sum%mod*(num[n-1].c-num[n-1].b+1)%mod)%mod;            }            else            {                sum=((sum%mod)*(1-qpow(num[n-1].a,num[n-1].c-num[n-1].b+1))%mod*inv(1-num[n-1].a)%mod)%mod;            }            for(int i=n-2; i>=0; i--)            {                if(num[i].a==1)                {                    sum=(sum%mod*(num[i].c-num[i].b+1)%mod)%mod;                }                else                    sum=((sum%mod)*(1-qpow(num[i].a,num[i].c-num[i].b+1))%mod*inv(1-num[i].a)%mod)%mod;            }            printf("Case #%d: %lld\n",cas++,sum%mod);        }    }    return 0;}/*537 10 999999992 1 999999915654894 56 98565298*/


原创粉丝点击