UVA10870 Recurrences (矩阵快速幂及构造方法详解)

 

题意:

  F(n) =  a1 * F(n-1) + a2 * F(n-2)+ ···· + ad * F(n-d)。

  求给你的n 。 很明显这是一道矩阵快速幂的题目。

  

题解:

  [Fn-1, Fn-2, Fn-3, ···, Fn-d] * A(矩阵) = [Fn, Fn-1, Fn-2, ···, Fn-d+1] 。

  F = 第一个矩阵 * A的第一列, 所以A矩阵的第一列为(a1, a2 , ··· ad)。

  Fn = 第一个矩阵  * A的第二列, 所以A矩阵的第二列为(1, 0, 0,···, 0)。

  同理可以推出整个A矩阵:

  a1  1  0  ···     0

  a2  0  1  ···     0

  a3  0  0  ···     0

  ···  0  0  ···   1

  ad  0  0  0  0

 

  当n 小于等于d 的时候 直接输出。

  [ f(d), f(d-1), f(d-2), ···, f(2), f(1) ] * An-d =  [Fn, Fn-1, Fn-2, ···, Fn-d+1] 。

  

  

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <algorithm>
 6 #include <cmath>
 7 #include <vector>
 8 #include <queue>
 9 #include <map>
10 #include <stack>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 #define ms(a, b) memset(a, b, sizeof(a))
15 #define pb push_back
16 #define mp make_pair
17 const LL INF = 0x7fffffff;
18 const int inf = 0x3f3f3f3f;
19 const int maxn = 10+10;
20 int mod;
21 struct Matrix
22 {
23     LL c[maxn][maxn];
24 };//Matrix 矩阵
25 Matrix mult(Matrix a, Matrix b, int len)//矩阵乘法
26 {
27      Matrix hh={0};
28      for(int i=0;i<len;i++)
29         for(int j =0;j<len;j++)
30             for(int k = 0;k<len;k++){
31                 hh.c[i][j] += (a.c[i][k]*b.c[k][j])%mod;
32                 hh.c[i][j] %= mod;
33             }
34     return hh;
35 }
36 Matrix qpow_Matrix(Matrix a, int b, int len)
37 {
38     Matrix base = a;
39     Matrix ans;
40     //初始化ans = 1。
41     for(int i =0;i<len;i++)
42         for(int j =0;j<len;j++)
43             if(i==j)    ans.c[i][j] = 1;
44             else ans.c[i][j] = 0;
45     //
46     while(b){
47         if(b&1)     ans = mult(ans, base, len);
48         base = mult(base, base, len);
49         b>>=1;
50     }
51     return ans;
52 }
53 int a[maxn];
54 int f[maxn];
55 void solve(int d, int n, int m){
56     mod = m;
57     for(int i = 1;i<=d;i++) cin >> a[i];
58     for(int i = 1;i<=d;i++) cin >> f[i];
59 
60     Matrix begin={0};
61     for(int j = 0;j<d;j++){
62         begin.c[0][j] = f[d-j]%mod;
63     }
64     Matrix A={0};
65     for(int j = 0;j<d;j++)
66         A.c[j][0] = a[j+1]%mod;
67     for(int j = 0;j<d;j++){
68         A.c[j][j+1] = 1;
69     }
70     if(n<=d){
71         cout << f[n]%mod << endl;
72         return;
73     }
74     Matrix temp = qpow_Matrix(A, n-d, d);
75     Matrix ans = mult(begin, temp, d);
76     cout << ans.c[0][0]%mod << endl;
77     return;
78 }
79 int main() {
80 #ifdef LOCAL
81     freopen("input.txt", "r", stdin);
82 //        freopen("output.txt", "w", stdout);
83 #endif
84 //    ios::sync_with_stdio(0);
85 //    cin.tie(0);
86     int d, n, m;
87     while(cin >> d >> n >> m){
88         if(d+n+m==0)    break;
89         solve(d, n, m);
90     }
91     return 0;
92 }
View Code

 

posted @ 2017-07-24 20:53  Dh_q  阅读(754)  评论(0编辑  收藏  举报