您的位置:首页 > 其它

HDU 4549 M斐波那契数列(矩阵快速幂+快速幂+欧拉降幂)

2016-10-28 15:40 357 查看

题目分析

这道题就是给a,b,n,让你求最后的结果,先找规律,多写几项就会发现a和b的指数是菲波那切数列,但是指数太大,axbymod1000000007这样还需要运用欧拉降幂得到ax mod1000000007by mod1000000007mod1000000007,这样一来就很好解决了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
const LL mod = 1000000007;

struct Matrix{
LL mat[2][2];
};

Matrix Mul(Matrix a, Matrix b){
Matrix ret;
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2; j++){
ret.mat[i][j] = 0;
for(int k = 0; k < 2; k++)
ret.mat[i][j] += a.mat[i][k]*b.mat[k][j];
ret.mat[i][j] %= (mod-1);  //欧拉降幂
}
}
return ret;
}

Matrix Mat_pow(Matrix a, LL n){  //矩阵快速幂
Matrix ret;
memset(ret.mat, 0, sizeof(ret.mat));
for(int i = 0; i < 2; i++) ret.mat[i][i] = 1;
while(n){
if(n&1) ret = Mul(ret, a);
a = Mul(a, a);
n >>= 1;
}
return ret;
}

LL Quick_pow(LL a, LL n){  //快速幂
LL ret = 1;
while(n){
if(n&1) ret = (ret*a)%mod;
a = (a*a)%mod;
n >>= 1;
}
return ret;
}

void init(Matrix& temp){
temp.mat[0][0] = 1,temp.mat[0][1] = 1,temp.mat[1][0] = 1,temp.mat[1][1] = 0;
}

int main(){
LL a, b, n;
while(scanf("%I64d%I64d%I64d", &a, &b, &n) != EOF){
if(n == 0) printf("%I64d\n", a%mod);
else if(n == 1) printf("%I64d\n", b%mod);
else{
Matrix temp, ans;
init(temp);
ans = Mat_pow(temp, n-2);
LL x = ans.mat[0][0];
init(temp);
ans = Mat_pow(temp, n-1);
LL y = ans.mat[0][0];
printf("%I64d\n", (Quick_pow(a, x)*Quick_pow(b, y))%mod);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: