• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
james1207

博客园    首页    新随笔    联系   管理    订阅  订阅

利用矩阵快速幂求斐波那契数列

我们知道如果用记忆化搜索逐项递推可以将复杂度降低到O(n),但是对于更大规模的输入,这个算法效率还是不够高,那么我们考虑更高效的算法:

二阶递推:f(n+2)=(1 1) f(n+1)

                 f(n+1)  (1 0)   f(n)

上面等式两边分别是矩阵,那么矩阵A就是等式右边第一个式子。

只要求出A的n次,就可以求出f(n)。我们使用快速幂来求,这个算法的复杂度为O(logn)

 

#include <iostream>
#include <cstddef>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
const int mod=10000;
typedef vector<ll> vec;
typedef vector<vec> mat;
mat mul(mat &a,mat &b){
	mat c(a.size(),vec(b[0].size()));
	for(int i=0;i<2;i++){
		for(int j=0;j<2;j++){
			for(int k=0;k<2;k++){
				c[i][j]+=a[i][k]*b[k][j];
				//c[i][j]%=mod;
			}
		}
	}
	return c;
}
mat pow(mat a,ll n){
	mat res(a.size(),vec(a.size()));
	for(int i=0;i<a.size();i++)
		res[i][i]=1;
	while(n>0){
		if(n&1){
			res=mul(res,a);
			n-=1;
		}
		else{
			a=mul(a,a);
			n/=2;
		}
	}
	return res;
}
ll solve(ll n){
	mat a(2,vec(2));
	a[0][0]=1;a[0][1]=1;
	a[1][0]=1;a[1][1]=0;
	a=pow(a,n);
	return a[1][0];
}

int main(){
	ll n;
	while(cin>>n){
		cout<<solve(n)<<endl;
	}
	return 0;
} 


 

 

posted @ 2013-08-25 21:29  Class Xman  阅读(417)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3