UVA Recurrences 矩阵相乘+快速幂
题目大意:
f(n) = a1 f(n - 1) + a2 f(n - 2) + a3 f(n - 3) + ... + ad f(n - d),已给递推公式,求f(n)的大小。
解题思路:
n很大,所以我们就要构造矩阵,运用矩阵快速幂来求解。//题目描述上口口声声说int范围内,但是大家一定不要天真!!!!!!
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <cstring> 8 using namespace std; 9 10 #define LL long long 11 const int maxn = 18; 12 LL d, m; 13 struct mat 14 { 15 LL p[maxn][maxn]; 16 }; 17 18 mat mul (mat a, mat b); 19 mat pow (LL n, mat a, mat b); 20 21 int main () 22 { 23 LL n; 24 mat a, b; 25 26 while (scanf ("%lld %lld %lld", &d, &n, &m), n+m+d) 27 { 28 memset (a.p, 0, sizeof(a.p)); 29 memset (b.p, 0, sizeof(b.p)); 30 31 for (int i=0; i<d; i++)//构造矩阵 32 { 33 scanf ("%lld", &a.p[i][0]); 34 a.p[i][0] %= m; 35 a.p[i][i+1] = 1; 36 } 37 for (int i=0; i<d; i++)//这个矩阵要反过来输入!!!!!! 38 { 39 scanf ("%lld", &b.p[0][d-i-1]); 40 b.p[0][i] %= m; 41 } 42 43 44 if (d < n) 45 { 46 b = pow (n-d, a, b); 47 printf ("%lld\n", b.p[0][0]); 48 } 49 else 50 printf ("%lld\n", b.p[0][d-n]); 51 } 52 return 0; 53 } 54 55 mat mul (mat a, mat b) 56 { 57 mat c; 58 memset (c.p, 0, sizeof(c.p)); 59 for (int i=0; i<d; i++) 60 for (int j=0; j<d; j++) 61 { 62 for (int k=0; k<d; k++) 63 c.p[i][j] = (c.p[i][j] + a.p[i][k] * b.p[k][j]) % m; 64 } 65 return c; 66 } 67 mat pow (LL n, mat a, mat b) 68 { 69 while (n) 70 { 71 if (n % 2) 72 b = mul (b, a); 73 a = mul (a, a); 74 n /= 2; 75 } 76 return b; 77 }
本文为博主原创文章,未经博主允许不得转载。