1. 程式人生 > 其它 >【SSL 例5】前n項的和【矩陣乘法】

【SSL 例5】前n項的和【矩陣乘法】

技術標籤:SSLOnlineJudge數論矩陣乘法

題目描述:

數列 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; }