• 题解 [51nod1358] 浮波那契


    题解 [51nod1358] 浮波那契

    题面

    解析

    首先根据经验应该能一眼矩阵快速幂加速....

    因为给了你递推式,并且(O(n))求显然不可能.

    所以考虑怎么构造矩阵.

    首先要处理的是小数的问题,

    这里我们可以把(n)扩大5倍,

    那么就变成了

    [egin{equation}f(n)=left{ egin{array}{**lr**} 1 ,nleq20 & \ f(n-5)+f(n-17),otherwise end{array} ight.end{equation} ]

    然后考虑怎么构造矩阵,

    想一想,一开始矩阵应该是这个样子:

    [left[ egin{matrix} f(n-1)&f(n-2)&dots&f(n-17) end{matrix} ight] ]

    乘上一个矩阵得到

    [left[egin{matrix}f(n)&f(n-1)dots&f(n-16)end{matrix} ight] ]

    然后因为有重复的项我们就设为(1),再把递推的地方设为(1),其它地方设为(0).

    讲的太不清楚了还是直接看矩阵吧

    [left[egin{matrix}01000000000000000&\00100000000000000&\00010000000000000&\00001000000000000&\10000100000000000&\00000010000000000&\00000001000000000&\00000000100000000&\00000000010000000&\00000000001000000&\00000000000100000&\00000000000010000&\00000000000001000&\00000000000000100&\00000000000000010&\00000000000000001&\10000000000000000&\end{matrix} ight] ]

    实际上结合矩阵乘法想一想应该就行了.

    接下来直接跑矩阵快速幂即可.

    code:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #define ll long long
    using namespace std;
    
    inline int read(){
    	int sum=0,f=1;char c=getchar();
    	while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
    	while(c<='9'&&c>='0'){sum=sum*10+c-'0';c=getchar();}
    	return f*sum;
    }
    
    const int N=101;
    const int Mod=1000000007;
    struct mat{
    	ll f[N][N];
    	inline void clear(){memset(f,0,sizeof f);}
    	inline void init(){clear();for(int i=0;i<N;i++) f[i][i]=1;}
    }a,b;
    ll n;
    
    inline mat operator*(mat a,mat b){
    	mat c;c.clear();
    	for(int k=0;k<17;k++){
    		for(int i=0;i<17;i++){
    			ll t=a.f[i][k];
    			for(int j=0;j<17;j++) c.f[i][j]=(c.f[i][j]+t*b.f[k][j])%Mod;
    		}
    	}
    	return c;	
    }
    
    inline mat fpow(mat a,ll b){
    	mat ret;ret.init();
    	for(;b;a=a*a,b>>=1) if(b&1) ret=ret*a;
    	return ret;
    }
    
    signed main(){
    	n=read();
    	if(n<=4){puts("1");return 0;}
    	for(int i=0;i<17;i++) a.f[0][i]=1;
    	for(int i=0;i<16;i++) b.f[i][i+1]=1;
    	b.f[4][0]=1;b.f[16][0]=1;
    	a=a*fpow(b,n*5-20);
    	printf("%lld
    ",a.f[0][0]);
    	return 0;
    }
    
    
  • 相关阅读:
    spring data jpa 分页查询(小结)
    java 工作日判断
    Map的merge方法(java8)
    java8 常用JVM 参数修改
    ubuntu docker client 安装
    scala io 读写文件
    Grafana 系统资源监测
    Java8Stream Collectors收集器
    EhCacheUtils 缓存 ehche (将文件临时保存在磁盘)
    springboot2.X 整合scala
  • 原文地址:https://www.cnblogs.com/zsq259/p/11864143.html
Copyright © 2020-2023  润新知