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

我们知道如果用记忆化搜索逐项递推可以将复杂度降低到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;

} 


 

 

你可能感兴趣的:(矩阵)