51Nod - 1242 斐波那契数列的第N项

本文介绍了一种高效求解斐波那契数列的方法——矩阵快速幂。针对大数问题,传统递推法无法满足效率需求,通过矩阵快速幂可在对数时间内求得结果。文中给出了具体的C++实现代码。

题目链接:点击打开链接

题意:中文题意不解释了。

题解:n的大小为 10的18次方,用递推方程 F【n】 = F【n-1】 + F【n-2】时间绝对会超时。所以用一种特殊的技巧。矩阵快速幂。

初始矩阵为

1 0

0 1

转化矩阵为

1 1

1 0 

不懂矩阵快速幂的可以看一下我的这篇博客:https://blog.youkuaiyun.com/pk__pk/article/details/78954671

所以代码为:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
const long long mod = 1000000009;
struct mat{
	long long m[2][2];
}ans;

mat base = {1,1,1,0};

mat multi(mat a,mat b){
	mat tmp;
	for(long long i = 0 ; i < 2 ; i ++){
		for(long long j = 0 ; j < 2 ; j ++){
			tmp.m[i][j] = 0;
			for(long long k = 0 ; k < 2 ; k ++){
				tmp.m[i][j] += (a.m[i][k]*b.m[k][j])%mod;
				tmp.m[i][j] %= mod;
			}
				
		}
	}
	return tmp;
}

long long mat_pow(mat a,long long n){
	ans.m[0][0] = ans.m[1][1] = 1;
	ans.m[0][1] = ans.m[1][0] = 0;
	while(n){
		if(n&1)
			ans = multi(ans,a);
			a = multi(a,a);
			n >>= 1;
	} 
	return ans.m[0][1];
}
int main(){
	long long n ;
	cin >> n;
	cout << mat_pow(base,n) << endl;
	

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值