HDU 5793 A Boring Question【快速幂+逆元】

来源:互联网 发布:kali安装wine源码包 编辑:程序博客网 时间:2024/06/06 15:44

A Boring Question

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 870    Accepted Submission(s): 539


Problem Description
There are an equation.
0k1,k2,kmn1j<m(kj+1kj)%1000000007=?
We define that (kj+1kj)=kj+1!kj!(kj+1kj)! . And (kj+1kj)=0 while kj+1<kj.
You have to get the answer for each n and m that given to you.
For example,if n=1,m=3,
When k1=0,k2=0,k3=0,(k2k1)(k3k2)=1;
Whenk1=0,k2=1,k3=0,(k2k1)(k3k2)=0;
Whenk1=1,k2=0,k3=0,(k2k1)(k3k2)=0;
Whenk1=1,k2=1,k3=0,(k2k1)(k3k2)=0;
Whenk1=0,k2=0,k3=1,(k2k1)(k3k2)=1;
Whenk1=0,k2=1,k3=1,(k2k1)(k3k2)=1;
Whenk1=1,k2=0,k3=1,(k2k1)(k3k2)=0;
Whenk1=1,k2=1,k3=1,(k2k1)(k3k2)=1.
So the answer is 4.
 

Input
The first line of the input contains the only integer T,(1T10000)
Then T lines follow,the i-th line contains two integers n,m,(0n109,2m109)
 

Output
For each n and m,output the answer in a single line.
 

Sample Input
21 22 3
 

Sample Output
313
 

Author
UESTC
 

Source
2016 Multi-University Training Contest 6

题解:

打表找规律。。。

f(1,2)=3; f(2,2)=7;
f(1,3)=4; f(2,3)=13;
f(1,4)=5; f(2,4)=21;
f(1,5)=6; f(2,5)=31;
......
规律:
f(n,m) = f(n-1,m) + m^n;
= m^0 + m^1 + m^2 + ... + m^n; (等比数列求和)
= (1 - m^(n+1)) / (1 - m);
然后用快速幂和乘法逆元求出上式即可.

官方题解:


#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<queue>#include<stack>#include<vector>#include<map>#include<set>#include<algorithm>using namespace std;#define ll long long#define ms(a,b)  memset(a,b,sizeof(a))const int M=1e3+10;const int inf=0x3f3f3f3f;const int mod=1e9+7;ll i,j,k,n,m;ll x,y,gcd;ll quickmod(ll a,ll b,ll mod){    ll ans=1;    a%=mod;    while(b){        if(b&1){            ans=(ans*a)%mod;        }        a=(a*a)%mod;        b>>=1;    }    return ans;}void ex_gcd(ll a,ll b){    if(!b){x=1;y=0;gcd=a;}    else {        ex_gcd(b,a%b);        ll temp=x;        x=y;y=temp-a/b*y;    }}ll extgcd(ll a, ll b, ll& x, ll& y){    ll d = a;    if(b != 0){        d = extgcd(b, a % b, y, x);        y -= (a / b) * x;    }else {        x = 1;        y = 0;    }    return d;}ll mod_inverse(ll a, ll m){    ll x, y;    extgcd(a, m, x, y);    return (m + x % m) % m;}int main(){    int t;    scanf("%d",&t);    while(t--){        scanf("%lld%lld",&n,&m);        ll ans1=quickmod(m,n+1,mod)-1;        ll ans2=m-1;        ll x=mod_inverse(ans2,mod);        ll ans=(ans1*x)%mod;        printf("%lld\n",ans);    }    return 0;}



#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<queue>#include<stack>#include<vector>#include<map>#include<set>#include<algorithm>using namespace std;#define ll long long#define ms(a,b)  memset(a,b,sizeof(a))const int M=1e3+10;const int inf=0x3f3f3f3f;const int mod=1e9+7;ll i,j,k,n,m;ll x,y,gcd;ll quickmod(ll a,ll b,ll mod){    ll ans=1;    a%=mod;    while(b){        if(b&1){            ans=(ans*a)%mod;        }        a=(a*a)%mod;        b>>=1;    }    return ans;}void ex_gcd(ll a,ll b){    if(!b){x=1;y=0;gcd=a;}    else {        ex_gcd(b,a%b);        ll temp=x;        x=y;y=temp-a/b*y;    }}int main(){    int t;    scanf("%d",&t);    while(t--){        scanf("%lld%lld",&n,&m);        ll ans1=quickmod(m,n+1,mod)-1;        ll ans2=m-1;        ex_gcd(ans2,mod);        while(x<0){            x+=mod;            y-=ans2;        }        ll ans=(ans1*x)%mod;        printf("%lld\n",ans);    }    return 0;}




 

原创粉丝点击