蓝桥杯:递推求值(构造矩阵+矩阵快速幂)
http://lx.lanqiao.cn/problem.page?gpid=T396
题意:……
思路:自始至终不会构造矩阵,yr大佬手把手教我构造矩阵Orz。
先把有用的信息写成一个矩阵F,然后判断下一步要推出来的信息是怎么构成的,然后一行一行构造矩阵A。
最后将构造得到的矩阵A乘n次,再乘F,就可以得到答案了。
矩阵A的第一行就是F中的哪些信息可以构成F1(n),就选择性用上,以此类推可以构造出来。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define MOD 99999999 4 typedef long long LL; 5 6 struct Matrix { 7 LL mat[10][10]; int r, c; 8 Matrix () { memset(mat, 0, sizeof(mat)); } 9 Matrix (int a, int b) { r = a; c = b; memset(mat, 0, sizeof(mat)); } 10 void init() { memset(mat, 0, sizeof(mat)); } 11 void E() { memset(mat, 0, sizeof(mat)); for(int i = 1; i <= 9; i++) mat[i][i] = 1; } 12 }; 13 14 Matrix operator * (Matrix a, Matrix b) { 15 Matrix c = Matrix(a.r, b.c); 16 for(int i = 1; i <= a.r; i++) { 17 for(int k = 1; k <= a.c; k++) { 18 for(int j = 1; j <= b.c; j++) { 19 c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j] % MOD) % MOD; 20 } 21 } 22 } 23 return c; 24 } 25 26 Matrix operator ^ (Matrix a, LL k) { 27 Matrix p = Matrix(7, 7), tmp = a; 28 p.E(); 29 while(k) { 30 if(k & 1) p = p * tmp; 31 tmp = tmp * tmp; 32 k >>= 1; 33 } 34 return p; 35 } 36 37 void print(Matrix now) { 38 for(int i = 1; i <= now.r; i++) { 39 for(int j = 1; j <= now.c; j++) { 40 printf("%lld ", now.mat[i][j]); 41 } 42 puts(""); 43 } 44 } 45 46 int main() { 47 Matrix now = Matrix(7, 7); 48 now.mat[1][2] = 1; now.mat[1][5] = 2; now.mat[1][7] = 5; 49 now.mat[2][1] = 1; now.mat[2][5] = 3; now.mat[2][6] = 2; now.mat[2][7] = 3; 50 now.mat[3][1] = 1; 51 now.mat[4][2] = 1; 52 now.mat[5][3] = 1; 53 now.mat[6][4] = 1; 54 now.mat[7][7] = 1; 55 Matrix f = Matrix(7, 1); 56 f.mat[1][1] = 6; f.mat[2][1] = 5; f.mat[3][1] = 1; 57 f.mat[4][1] = 4; f.mat[5][1] = 2; f.mat[6][1] = 3; f.mat[7][1] = 1; 58 59 LL n; cin >> n; 60 if(n == 2) { printf("1\n4\n"); return 0; } 61 else if(n == 1) { printf("2\n3\n"); return 0; } 62 n -= 3; 63 Matrix ans = now ^ n; 64 ans = ans * f; 65 cout << ans.mat[1][1] << endl << ans.mat[2][1] << endl; 66 return 0; 67 }