例5:求斐波那契数列变形前n项的和【矩阵乘法】【快速幂】【斐波那契数列】

题目描述

数列 f [ n ] = f [ n − 1 ] + f [ n − 2 ] + n + 1 , f [ 1 ] = f [ 2 ] = 1 f[n]=f[n-1]+f[n-2]+n+1,f[1]=f[2]=1 f[n]=f[n1]+f[n2]+n+1,f[1]=f[2]=1 的前 n n n 项和 s [ n ] s[n] s[n] 的快速求法(不考虑高精度).

思路

求斐波那契数列前n项的和相似
转移矩阵为
∣ 0 1 0 0 0 1 1 1 0 0 0 0 1 0 0 0 1 0 1 0 0 1 0 1 1 ∣ \begin{vmatrix}0&1&0&0&0\\1&1&1&0&0\\0&0&1&0&0\\0&1&0&1&0\\0&1&0&1&1\end{vmatrix} 0100011011011000001100001

C o d e Code Code

#include
#include
#include
using namespace std;
const int mod=9973;
long long n,a[6][6],ans[6][6];
long long fd[6][6];
void jzcf(int m)
{
	long long c[6][6];
	for(int i=1; i<=m; i++)
	 for(int j=1; j<=m; j++)
	    c[i][j]=0;
	for(int i=1; i<=m; i++)
	 for(int j=1; j<=m; j++)
	  for(int k=1; k<=m; k++)
	     c[i][j]=(c[i][j]+(a[i][k]*ans[k][j])%mod)%mod;
	for(int i=1; i<=m; i++)
	 for(int j=1; j<=m; j++)
	    ans[i][j]=c[i][j];
}
void jzcf2(int m)
{
	long long c[6][6];
	for(int i=1; i<=m; i++)
	 for(int j=1; j<=m; j++)
	    c[i][j]=0;
	for(int i=1; i<=m; i++)
	 for(int j=1; j<=m; j++)
	  for(int k=1; k<=m; k++)
	     c[i][j]=(c[i][j]+(a[i][k]*a[k][j])%mod)%mod;
	for(int i=1; i<=m; i++)
	 for(int j=1; j<=m; j++)
	    a[i][j]=c[i][j];
}
void jzcf3()
{
	long long c[6][6];
	for(int i=1; i<=5; i++)
	 for(int j=1; j<=5; j++)
	    c[i][j]=0;
	for(int i=1; i<=1; i++)
	 for(int j=1; j<=5; j++)
	  for(int k=1; k<=5; k++)
	     c[i][j]=(c[i][j]+(fd[i][k]*ans[k][j])%mod)%mod;
	for(int i=1; i<=1; i++)
	 for(int j=1; j<=5; j++)
	    fd[i][j]=c[i][j];
}
void ksm(int k)
{
	for(int i=1; i<=3; i++)
	   ans[i][i]=1;
	while(k!=0)
	 {
	 	if(k&1)
	 	  jzcf(5);
	 	jzcf2(5);
	 	k>>=1;
	 }
}
int main()
{
	cin>>n;
	a[1][1]=0,a[1][2]=1,a[1][3]=0,a[1][4]=0,a[1][5]=0;
	a[2][1]=1,a[2][2]=1,a[2][3]=1,a[2][4]=0,a[2][5]=0;
	a[3][1]=0,a[3][2]=0,a[3][3]=1,a[3][4]=0,a[3][5]=0;
	a[4][1]=0,a[4][2]=1,a[4][3]=0,a[4][4]=1,a[4][5]=0;
	a[5][1]=0,a[5][2]=1,a[5][3]=0,a[5][4]=1,a[5][5]=1;
	fd[1][1]=1,fd[1][2]=1,fd[1][3]=1,fd[1][4]=3,fd[1][5]=1;
	ksm(n-1);
	jzcf3();
    cout<<fd[1][3];
	return 0;
}

你可能感兴趣的:(题解,矩阵乘法,快速幂,斐波那契数列)