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 long d, n, m;

Mat multiply(Mat x, Mat y) {
    Mat temp;
    for (int i = 0; i < d; i++)
        for (int j = 0; j < d; j++) {
            temp.g[i][j] = 0;
            for (int k = 0; k < d; k++)
                temp.g[i][j] = (temp.g[i][j] + x.g[i][k] * y.g[k][j]) % m;
        }
    return temp;
}

void calc(long long n) {
    while (n) {
        if (n & 1)
            ori = multiply(ori, res);
        n >>= 1;
        res = multiply(res, res);
    }
}

int main() {
    while (scanf("%lld%lld%lld", &d, &n, &m) && d + n + m) {
        memset(res.g, 0, sizeof(res.g));
        memset(ori.g, 0, sizeof(ori.g));
        for (int i = 0; i < d; i++) {
            scanf("%lld", &res.g[i][0]);
            res.g[i][0] %= m;
            if (i > 0)
                res.g[i - 1][i] = 1;
        }
        for (int i = 0; i < d; i++) {
            scanf("%lld", &ori.g[0][d - 1 - i]);
            ori.g[0][d - 1 - i] %= m;
        }
        calc(n - d);
        printf("%lld\n", ori.g[0][0]);
    }
    return 0;
}
时间: 2024-12-23 19:00:14

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

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[ma

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