uva 10870 Recurrences(矩阵快速幂)

类似斐波那契,d为几构造几阶的矩阵即可。

题目:点击打开链接

代码:

#include
using namespace std;
typedef long long ll;
ll d, n, m, a[16], f[16];
struct node
{
    ll s[16][16];
    void init(void) { memset(s, 0, sizeof(s)); }
};

void print(node a)
{
    printf("\n");
    for(int i = 1; i <= d; i++)
        for(int j = 1; j <= d; j++)
        {
            printf("%lld ", a.s[i][j]);
            if(j == d) printf("\n");
        }
    printf("\n");
}

node mul(node a, node b)
{
    node t;
    t.init();
    for(int i = 1; i <= d; i++)
        for(int j = 1; j <= d; j++)
            for(int k = 1; k <= d; k++)
                t.s[i][j] = (t.s[i][j]+a.s[i][k]*b.s[k][j])%m;
    return t;
}

node mt_pow(node p, ll k)
{
    node q;
    q.init();
    for(int i = 1; i <= d; i++) q.s[i][i] = 1;
    while(k)
    {
        if(k&1) q = mul(p, q);
        p = mul(p, p);
        k /= 2;
    }
    return q;
}

int main(void)
{
    while(cin >> d >> n >> m, d+n+m)
    {
        for(int i = 1; i <= d; i++) scanf("%lld", &a[i]);
        for(int i = 1; i <= d; i++) scanf("%lld", &f[i]);
        node base;
        base.init();
        for(int i = 1; i <= d; i++) base.s[1][i] = a[i];
        for(int i = 2; i <= d; i++) base.s[i][i-1] = 1;
//        print(base);
        node ans = mt_pow(base, n-d);
        ll res = 0;
        for(int i = 1; i <= d; i++)
            res = (res+ans.s[1][i]*f[d-i+1])%m;
        printf("%lld\n", res);
    }
    return 0;
}



你可能感兴趣的:(矩阵)