1. 程式人生 > >[矩陣快速冪] 數列(類斐波那契

[矩陣快速冪] 數列(類斐波那契

題目 str ons 矩陣 include ron eof 100% align

數列

題目描述

a[1]=a[2]=a[3]=1

a[x]=a[x-3]+a[x-1]
求a數列的第n項對1000000007(10^9+7)取余的值。

輸入

第一行一個整數T,表示詢問個數。

以下T行,每行一個正整數n。

輸出

每行輸出一個非負整數表示答案。

樣例輸入

3
6
8
10

樣例輸出

4
9
19

提示

對於30%的數據 n<=100;


對於60%的數據 n<=2*10^7;


對於100%的數據 T<=100,n<=2*10^9;

emmm基本就是一道矩陣快速冪的裸題,根據題目需要自己求得矩陣套進去即可

(順便一提,學校OJ裏輸出1的情況沒有換行竟然只有18分orz 調試了半天不知道錯在哪裏

下面放上代碼

 1 #include<cstdio>
 2 #include<cstring>
 3  
 4 const int Mod = 1e9 + 7; 
 5  
 6 struct Matrix {
 7     long long m[3][3]; 
 8 }; 
 9  
10 Matrix Mult(Matrix a, Matrix b) {
11     long long sums = 0; 
12     Matrix c; 
13     memset(c.m, 0, sizeof(c.m)); 
14     for (int i = 0; i <= 2
; i++) { 15 for (int j = 0; j <= 2; j++) { 16 sums = 0; 17 for (int k = 0; k <= 2; k++) { 18 sums = (sums + a.m[i][k] * b.m[k][j]) % Mod; 19 } 20 c.m[i][j] = sums; 21 } 22 } 23 return c; 24 } 25 26 Matrix Qpow(Matrix a, int
k) { 27 Matrix res; 28 memset(res.m, 0, sizeof(res.m)); 29 for (int i = 0; i <= 2; i++) { 30 res.m[i][i] = 1; 31 } 32 while(k) { 33 if (k & 1) { 34 res = Mult(res, a); 35 } 36 a = Mult(a, a); 37 k = (k >> 1); 38 } 39 return res; 40 } 41 42 int main() { 43 long long n; 44 int t; 45 scanf("%d", &t); 46 for (int cnt = 1; cnt <= t; cnt++) { 47 Matrix A, B; 48 memset(A.m, 0, sizeof(A.m)); 49 memset(B.m, 0, sizeof(B.m)); 50 scanf("%lld", &n); 51 if (n <= 3) { 52 printf("1\n"); 53 continue; 54 } 55 for (int i = 0; i < 3; i++) { 56 A.m[i][i + 1] = 1; 57 } 58 A.m[2][0] = 1; 59 A.m[2][2] = 1; 60 for (int i = 0; i < 3; i++) { 61 B.m[i][0] = 1; 62 } 63 A = Qpow(A, n - 3); 64 A = Mult(A, B); 65 printf("%d\n", A.m[2][0]); 66 } 67 return 0; 68 }

[矩陣快速冪] 數列(類斐波那契