[矩阵快速幂] 数列(类斐波那契
Posted GldHkkowo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[矩阵快速幂] 数列(类斐波那契相关的知识,希望对你有一定的参考价值。
数列
题目描述
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 }
以上是关于[矩阵快速幂] 数列(类斐波那契的主要内容,如果未能解决你的问题,请参考以下文章