uva 10870 - Recurrences(矩阵快速幂)

来源:互联网 发布:淘宝网如何做推广 编辑:程序博客网 时间:2024/05/21 21:49

题目链接:uva 10870 - Recurrences

题目大意:考虑线性递推,给出递推方程,求f(n)%m.

解题思路:矩阵快速幂。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxsize = 100;typedef long long ll;typedef long long type;type MOD;struct Mat {    int r, l;    type arr[maxsize][maxsize];    Mat (int r = 0, int l = 0) {         set(r, l);        memset(arr, 0, sizeof(arr));    }    void set (int r, int l) {        this->r = r;        this->l = l;    }    Mat operator * (const Mat& u) {        Mat ret(r, u.l);        for (int k = 0; k < l; k++) {            for (int i = 0; i < r; i++)                for (int j = 0; j < u.l; j++)                    ret.arr[i][j] = (ret.arr[i][j] + arr[i][k] * u.arr[k][j]) % MOD;        }        return ret;    }};void put (Mat x) {    for (int i = 0; i < x.r; i++) {        for (int j = 0; j < x.l; j++)            printf("%lld ", x.arr[i][j]);        printf("\n");    }}Mat pow_mat (Mat ans, Mat x, ll n, ll m) {    MOD = m;    while (n) {        if (n&1)            ans = x * ans;        x = x * x;        n >>= 1;    }    return ans;}int main () {    int D;    ll N, M;    while (scanf("%d%lld%lld", &D, &N, &M) == 3 && D + N + M) {        Mat x(D, D);        for (int i = 1; i < D; i++)            x.arr[i-1][i] = 1;        for (int i = 0; i < D; i++) {            scanf("%lld", &x.arr[D-1][D-1-i]);            x.arr[D-1][D-1-i] %= M;        }        Mat ans(D, 1);        for (int i = 0; i < D; i++) {            scanf("%lld", &ans.arr[i][0]);            ans.arr[i][0] %= M;        }        if (N > D) {            Mat tmp = pow_mat(ans, x, N - D, M);            printf("%lld\n", tmp.arr[D-1][0]);        } else            printf("%lld\n", ans.arr[N-1][0]);    }    return 0;}
0 0
原创粉丝点击