题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1757
题目大意:
求递推式第k项模m
If x < 10 f(x) = x.
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
And ai(0<=i<=9) can only be 0 or 1 .
解题思路:
构建矩阵
直接用矩阵快速幂模板求解
注意,小于10的时候不能直接输出k,要输出k%m
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 100 + 10; 4 int MOD; 5 struct Mat 6 { 7 int a[maxn][maxn]; 8 int n, m;//n为行数,m为列数 9 Mat(int n, int m):n(n), m(m) 10 { 11 memset(a, 0, sizeof(a)); 12 } 13 void init() 14 { 15 for(int i = 0; i < n; i++)a[i][i] = 1;//初始化成单位矩阵 16 } 17 void output() 18 { 19 for(int i = 0; i < n; i++) 20 { 21 for(int j = 0; j < m; j++) 22 { 23 cout<<a[i][j]<<" "; 24 } 25 cout<<endl; 26 } 27 } 28 }; 29 Mat mul(Mat a, Mat b)//矩阵乘法 30 { 31 Mat tmp(a.n, b.m);//矩阵乘法结果矩阵行数为a的行数,列数为b的列数 32 for(int i = 0; i < a.n; i++) 33 { 34 for(int j = 0; j < b.m; j++) 35 { 36 for(int k = 0; k < a.m; k++)//a.m == b.n(乘法的前提条件) 37 { 38 tmp.a[i][j] += (a.a[i][k] * b.a[k][j] % MOD); 39 tmp.a[i][j] %= MOD; 40 } 41 } 42 } 43 return tmp; 44 } 45 Mat pow(Mat a, int n) 46 { 47 Mat tmp(a.n, a.m); 48 tmp.init(); 49 while(n) 50 { 51 if(n & 1)tmp = mul(tmp, a); 52 n /= 2; 53 a = mul(a, a); 54 } 55 return tmp; 56 } 57 int main() 58 { 59 int n, m; 60 while(cin >> n >> m) 61 { 62 Mat a(10, 10); 63 Mat b(10, 1); 64 //对a和b进行初始化 65 for(int i = 0; i < 10; i++)cin >> a.a[0][i]; 66 for(int i = 1; i < 10; i++)a.a[i][i - 1] = 1; 67 for(int i = 0; i < 10; i++)b.a[i][0] = 9 - i; 68 MOD = m; 69 //a.output(); 70 //b.output(); 71 if(n < 10) 72 { 73 cout<<(n % m)<<endl; 74 } 75 else 76 { 77 Mat ans = pow(a, n - 9); 78 //ans.output(); 79 ans = mul(ans, b); 80 cout<<ans.a[0][0]<<endl; 81 } 82 } 83 }