您的位置:首页 > 其它

HDU 4549 M斐波那契数列 (矩阵快速幂+费马小定理)

2017-08-09 11:00 435 查看

思路:

通过列出几项我们就可以发现ab的指数是斐波那契数列。然后博主就开(智)心(障)的用矩阵快速幂算指数了。。

却忘了一件事。。。谁说的取模对指数封闭的啊???md疯狂wa了六七次。

取模对乘法封闭但不意味着指数你可以直接取模啊。。

正解是根据费马小定理:

ab=cmodp

当 gcd(a,p)=1 并且p是素数的时候,有:ap−1=1modp 也就是说,指数上循环节为0 1 2 。。。。p-1,所以我们可以对指数模(1e9+7-1)。

好了,结果出来了。

#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

;
};
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
e577
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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: