[矩陣快速冪] 數列(類斐波那契
阿新 • • 發佈:2018-04-14
題目 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, intk) { 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 }
[矩陣快速冪] 數列(類斐波那契