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


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


  • 相关阅读:
    POST GET原理函数
    位宽与带宽
    编程小工具
    C#的四个基本技巧
    关闭弹出模态窗口以后刷新父窗口
    十年技术,不要再迷茫
    冒泡排序
    单元测试工具及资源推荐
    xml xhtml html dhtml的区别
    删除List<string>中重复的值
  • 原文地址:https://www.cnblogs.com/james1207/p/3281413.html
Copyright © 2020-2023  润新知