博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

题解 [51nod1358] 浮波那契

题解 [51nod1358] 浮波那契

题面

解析

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

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

所以考虑怎么构造矩阵.

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

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

那么就变成了

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

然后考虑怎么构造矩阵,

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

\[\left[ \begin{matrix} f(n-1)&f(n-2)&\dots&f(n-17) \end{matrix} \right] \]

乘上一个矩阵得到

\[\left[\begin{matrix}f(n)&f(n-1)\dots&f(n-16)\end{matrix}\right] \]

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

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

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

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

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

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\n",a.f[0][0]);
	return 0;
}

posted @ 2019-11-15 08:35  Hastin  阅读(185)  评论(0编辑  收藏  举报