UVa 10870 (矩阵快速幂) Recurrences

给出一个d阶线性递推关系,求f(n) mod m的值。

,

求出An-dv0,该向量的最后一个元素就是所求。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5
 6 const int maxn = 20;
 7
 8 typedef long long Matrix[maxn][maxn];
 9 typedef long long Vector[maxn];
10
11 int d, n, m;
12
13 void matrix_mul(Matrix A, Matrix B, Matrix res)
14 {
15     Matrix C;
16     memset(C, 0, sizeof(C));
17     for(int i = 0; i < d; i++)
18         for(int j = 0; j < d; j++)
19             for(int k = 0; k < d; k++)
20                 C[i][j] = (C[i][j] + A[i][k]*B[k][j]) % m;
21     memcpy(res, C, sizeof(C));
22 }
23
24 void matrix_pow(Matrix A, int n, Matrix res)
25 {
26     Matrix a, r;
27     memcpy(a, A, sizeof(a));
28     memset(r, 0, sizeof(r));
29     for(int i = 0; i < d; i++) r[i][i] = 1;
30     while(n)
31     {
32         if(n&1) matrix_mul(r, a, r);
33         n >>= 1;
34         matrix_mul(a, a, a);
35     }
36     memcpy(res, r, sizeof(r));
37 }
38
39 int main()
40 {
41     //freopen("in.txt", "r", stdin);
42
43     while(cin >> d >> n >> m && d)
44     {
45         Matrix A;
46         memset(A, 0, sizeof(A));
47         Vector a, f;
48         for(int i = 0; i < d; i++) { cin >> a[i]; a[i] %= m; }
49         for(int i = 0; i < d; i++) { cin >> f[i]; f[i] %= m; }
50         if(n <= d) { cout << f[n-1] << "\n"; continue; }
51         for(int i = 0; i < d-1; i++) A[i][i+1] = 1;
52         for(int i = 0; i < d; i++) A[d-1][i] = a[d-i-1];
53         matrix_pow(A, n-d, A);
54         long long ans = 0;
55         for(int i = 0; i < d; i++) ans = (ans + A[d-1][i]*f[i]) % m;
56         cout << ans << "\n";
57     }
58
59     return 0;
60 }

代码君

时间: 2024-07-31 03:13:16

UVa 10870 (矩阵快速幂) Recurrences的相关文章

uva 10870(矩阵快速幂)

题意:计算f(n) f(n) = a1 f(n - 1) + a2 f(n - 2) + a3 f(n - 3) + - + ad f(n - d), for n > d. 题解:斐波那契的变形,把2个扩大成d个,然后加了a1-ad的参数,构造矩阵直接矩阵快速幂计算. #include <stdio.h> #include <string.h> const int N = 20; struct Mat { long long g[N][N]; }res, ori; long

uva 12470(矩阵快速幂)

题意:公式f(n) = f(n - 1) + f(n - 2) + f(n - 3),给出n,f(1) = 0,f(2) = 1, f(3) = 2,要求得出f(n). 题解:普通的矩阵快速幂模板题. #include <stdio.h> #include <string.h> const int MOD = 1000000009; struct Mat { long long g[3][3]; }ori, res; long long n; Mat multiply(Mat x,

UVA 10870 - Recurrences(矩阵快速幂)

UVA 10870 - Recurrences 题目链接 题意:f(n) = a1 f(n - 1) + a2 f(n - 2) + a3 f(n - 3) + ... + ad f(n - d), for n > d. 已知前d项求第n项 思路:矩阵快速幂,对应矩阵为 |a1 a2 a3 ... ad| |1 0 0 ... 0 0 0| |0 1 0 ... 0 0 0| |0 0 1 ... 0 0 0| |0 0 0 ... 0 0 0| |0 0 0 ... 1 0 0| |0 0 0

UVA - 10229 - Modular Fibonacci (矩阵快速幂 + fibonacci)

题目传送:UVA - 10229 思路:就是简单的矩阵快速幂求fibonacci数列,然后注意可能中间结果会爆int,因为2^19有50多万 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include <stack> #includ

UVA 10655 - Contemplation! Algebra(矩阵快速幂)

UVA 10655 - Contemplation! Algebra 题目链接 题意:给定p, q, n代表p=a+b,q=ab求an+bn 思路:矩阵快速幂,公式变换一下得到(an+bn)(a+b)=an+1+bn+1+ab(an?1+bn?1),移项一下得到an+1+bn+1=(an+bn)p?q(an?1+bn?1) 这样就可以用矩阵快速幂求解了 代码: #include <stdio.h> #include <string.h> long long p, q, n; str

uva 11651 - Krypton Number System(矩阵快速幂)

题目链接:uva 11651 - Krypton Number System 题目大意:给定进制base,和分数score,求在base进制下,有多少个数的值为score,要求不能有连续相同的数字以及前导0.计算一个数的值即为相邻两位数的平方差和. 解题思路:因为score很大,所以直接dp肯定超时,但是即使对于base=6的情况,每次新添一个数score最大增加25(0-5),所以用dp[i][j]预处理出base平方以内的总数,然后用矩阵快速幂计算. #include <cstdio> #

UVA 11651 - Krypton Number System(DP+矩阵快速幂)

UVA 11651 - Krypton Number System 题目链接 题意:给一个进制base,一个分数score求该进制下,有多少数满足一下条件: 1.没有连续数字 2.没有前导零 3.分数为score,分数的计算方式为相邻数字的平方差的和 思路:先从dp入手,dp[i][j]表示组成i,最后一个数字为j的种数,然后进行状态转移,推出前面一步能构成的状态,也就是到dp[(b - 1) * (b - 1)][x]. 然后可以发现后面的状态,都可以由前面这些状态统一转移出来,这样就可以利用

uva 10743 - Blocks on Blocks(矩阵快速幂)

题目链接:uva 10743 - Blocks on Blocks 题目大意:问说n联骨牌有多少种,旋转镜像后相同不算同一组,一行的格子必须连续,如果答案大于10000,输出后四位. 解题思路:想了一下午的递推式,实在受不了,把推出的序列在网上搜了一下,有公式ai=5?ai?1?7?ai?2+4?ai?3 (i≥5) PS:哪位神人知道怎么推出来的请留言我,大恩不言谢~ #include <cstdio> #include <cstring> #include <algori

uva 11885 - Number of Battlefields(矩阵快速幂)

题目连接:uva 11885 - Number of Battlefields 题目大意:给出周长p,问多少种形状的周长为p的,并且该图形的最小包围矩阵的周长也是p,不包括矩形. 解题思路:矩阵快速幂,如果包含矩形的话,对应的则是斐波那契数列的偶数项,所以对应减去矩形的个数即可. #include <cstdio> #include <cstring> using namespace std; typedef long long ll; const ll MOD = 9876543