【矩阵乘法】幼儿园数学题I

题目大意

F [ n ] = ( 5 + 1 2 ) n − 1 F[n] = (\frac{\sqrt{5}+1}{2})^{n-1} F[n]=(25 +1)n1
F ( x ) F(x) F(x) 的前 n n n 项和。


这题。。。考数学。
实则求斐波那契数列前n项和。
于是构建矩阵-像这样。
使得一个【f[n-2],f[n-1],S[n-2]】的矩阵乘上它变成【f[n-1],f[n],S[n]】。
以此递推。

- f[n-1] f[n] S[n-1]
f[n-2] 0 1 0
f[n-1] 1 1 1
S[n-2] 0 1

这个构建出来的矩阵求个快速幂,再乘上初始矩阵即可得到答案。


Code

#include<cstdio>
long long n;
struct asdf{
    
     
	long long n,m; 
	long long k[5][5];  
} A,B,C;
asdf operator *(asdf aa, asdf bb){
    
       //矩阵乘法
	asdf cc;
	cc.n = aa.n; 
	cc.m = bb.m;
	for(long long i = 1; i <= cc.n; ++i)
	  for(long long j = 1 ;j <= cc.m; ++j)
	    cc.k[i][j] = 0;
	for(long long i = 1; i <= cc.n; ++i) 
	  for(long long j = 1; j <= cc.m; ++j)
	    for(long long l = 1; l <= aa.m; ++l)  
		  cc.k[i][j] = (cc.k[i][j] + aa.k[i][l] * bb.k[l][j] % 1000000007) % 1000000007; 
	return cc;  
}
asdf ksm(long long l){
    
       //快速幂
	if(l == 1) return A;
	asdf ll = ksm(l/2);
	if(l % 2 == 0) return ll * ll;
	return ll * ll * A; 
}
int main(){
    
    
	scanf("%lld",&n);
	if(n == 1){
    
    
		printf("1");
		return 0;
	}
	A.n = 3; A.m = 3;
	A.k[1][1] = A.k[1][3] = A.k[3][2] = A.k[1][3] = 0;  //构建矩阵
	A.k[2][1] = A.k[1][2] = A.k[2][2] = A.k[2][3] = A.k[3][3] = 1;  
	C.n = 1; C.m = 3;
	C.k[1][1] = C.k[1][2] = 1; C.k[1][3] = 1;  //初始矩阵
	B = ksm(n-1);
	B = C * B;
	printf("%lld",B.k[1][3]);   //输出和

猜你喜欢

转载自blog.csdn.net/qq_42937087/article/details/111567547