HDU 4549 M斐波那契數列 (矩陣快速冪+費馬小定理)
阿新 • • 發佈:2019-01-26
思路:
通過列出幾項我們就可以發現ab的指數是斐波那契數列。然後博主就開(智)心(障)的用矩陣快速冪算指數了。。
卻忘了一件事。。。誰說的取模對指數封閉的啊???md瘋狂wa了六七次。
取模對乘法封閉但不意味著指數你可以直接取模啊。。
正解是根據費馬小定理:
當
好了,結果出來了。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <queue>
#include <algorithm>
typedef long long int lli;
using namespace std;
const int mod = 1000000007;
const int n = 2;
struct mat{
lli ma[n][n];
};
mat operator * (mat &a,mat &b){
mat c;
const int mm = mod-1;
memset(c.ma,0,sizeof(c.ma));
for(int k=0;k<n;++k){
for (int i=0;i<n;++i){
for(int j=0;j<n;++j){
c.ma[i][j] += a.ma[i][k]%mm*(b.ma[k][j]%mm)%mm;
c.ma[i][j] %= mm;
}
}
}
return c;
}
mat qp(mat a,lli k){
mat c;
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
c.ma [i][j] = (i==j);
}
}
for(;k;k>>=1){
if(k&1) c=c*a;
a = a*a;
}
return c;
}
lli qp(lli a,lli x){
lli res = 1;a %= mod;
for(;x;x>>=1){
if(x&1){
res *= a;res %= mod;
}
a = a*a%mod;
}
return res;
}
int main(){
int a,b,n;
while(~scanf("%d%d%d",&a,&b,&n)){
mat zuo = {1,0, 0,0};
mat base = {1,1, 1,0};
if(n == 0){
printf("%d\n",a%mod);
continue;
}
else{
base = qp(base,n-1);
lli a1 = base.ma[0][1],b1 = base.ma[0][0];
lli ans = qp(a,a1)%mod;
ans = (ans*qp(b,b1))%mod;
printf("%lld\n",ans);
}
}
}