【SSL 例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]的快速求法
9973 9973 9973 m o d mod mod ( ( (不考虑高精度 ) ) )

样例:

i n p u t input input 1 : 1: 1:

100

o u t p u t output output 1 : 1: 1:

2528

i n p u t input input 2 : 2: 2:

1234567

o u t p u t output output 2 : 2: 2:

9860

分析:

矩阵乘法 . . .
考虑一个 1 ∗ 5 1*5 15的矩阵 A [ f n − 2 , f n − 1 , s n − 2 , n , 1 ] A[f_{n-2},f_{n-1},s_{n-2},n,1] A[fn2,fn1,sn2,n,1]
我们要找到一个矩阵 B B B 使得 : : :
[ f n − 1 , f n , s n − 1 , n + 1 , 1 ] = [ f n − 1 , f n − 2 + f n − 1 + n + 1 , s n − 2 + f n − 1 , n + 1 , 1 ] [f_{n-1},f_{n},s_{n-1},n+1,1]=[f_{n-1},f_{n-2}+f_{n-1}+n+1,s_{n-2}+f_{n-1},n+1,1] [fn1,fn,sn1,n+1,1]=[fn1,fn2+fn1+n+1,sn2+fn1,n+1,1]
可以构造 B B B为:
在这里插入图片描述
s s s就在 m a t r i x [ 1 ] [ 3 ] matrix[1][3] matrix[1][3]

CODE:

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
const int mod=9973;
long long n;
using namespace std;
struct matrix{
    
    
	int n,m;
	int F[11][11];
}A,B,C;
matrix operator *(matrix A,matrix B){
    
    
	matrix C;
	C.n=A.n,C.m=B.m;
	for(int i=1;i<=C.n;i++)
		for(int j=1;j<=C.m;j++)
			C.F[i][j]=0;
	for(int k=1;k<=A.m;k++)
		for(int i=1;i<=C.n;i++)
			for(int j=1;j<=C.m;j++)
				C.F[i][j]=(C.F[i][j]+(A.F[i][k]*B.F[k][j])%mod)%mod;  //矩阵乘法
	return C;
}
void ksm(long long x){
    
    
	if(x==1){
    
    
		B=A;
		return; 
	}
	ksm(x>>1);
	B=B*B;
	if(x&1) B=B*A;
}
int main(){
    
    
	scanf("%lld",&n);
	if(n==1){
    
    
		printf("1");
		return 0;
	}
	A.n=5,A.m=5;
	A.F[1][1]=0,A.F[1][2]=1,A.F[1][3]=0,A.F[1][4]=0,A.F[1][5]=0;
	A.F[2][1]=1,A.F[2][2]=1,A.F[2][3]=1,A.F[2][4]=0,A.F[2][5]=0;
	A.F[3][1]=0,A.F[3][2]=0,A.F[3][3]=1,A.F[3][4]=0,A.F[3][5]=0;
	A.F[4][1]=0,A.F[4][2]=1,A.F[4][3]=0,A.F[4][4]=1,A.F[4][5]=0;  //变换矩阵
	A.F[5][1]=0,A.F[5][2]=1,A.F[5][3]=0,A.F[5][4]=1,A.F[5][5]=1;
	ksm(n-1);
	C.n=1,C.m=5;
	C.F[1][1]=1,C.F[1][2]=1,C.F[1][3]=1,C.F[1][4]=3,C.F[1][5]=1;  //初始
	C=C*B;
	printf("%d",C.F[1][3]); 
	return 0; 
}

猜你喜欢

转载自blog.csdn.net/dgssl_xhy/article/details/111328492
SSL