POJ 3233 Matrix Power Series

POJ_3233

    如果我们把S(k)写成递推式的话,就是S(k)=A*S(k-1)+A,这样就可以将S(k)表示成矩阵的形式,从而应用二分矩阵来快速求解S(k)了。

    此外,在计算中间结果的时候尽量少取模,因为取模运算的效率确实很低。

    

#include<stdio.h>
#include<string.h>
#define MAXD 70
int N, K, M, cnt;
struct Matrix
{
    int a[MAXD][MAXD];
    void init()
    {
        memset(a, 0, sizeof(a));
    }
}mat[510];
int multiply(int x, int y)
{
    int i, j, k, z = ++ cnt;
    long long ans;
    for(i = 0; i < (N << 1); i ++)
        for(j = 0; j < (N << 1); j ++)
        {
            ans = 0;
            for(k = 0; k < (N << 1); k ++)
                ans += mat[x].a[i][k] * mat[y].a[k][j];
            mat[z].a[i][j] = ans % M;
        }
    return z;
}
void init()
{
    int i, j, k;
    cnt = 0;
    mat[0].init();
    for(i = 0; i < N; i ++)
        for(j = 0; j < N; j ++)
        {
            scanf("%d", &k);
            mat[0].a[i][j] = mat[0].a[i][j + N] = k;
            if(i == j)
                mat[0].a[i + N][j + N] = 1;
        }
}
int powmod(int n)
{
    int k;
    if(n == 1)
        return 0;
    k = powmod(n / 2);
    k = multiply(k, k);
    if(n & 1)
        k = multiply(k, 0);
    return k;
}
void solve()
{
    int i, j, k;
    k = powmod(K);
    for(i = 0; i < N; i ++)
    {
        printf("%d", mat[k].a[i][N]);
        for(j = 1; j < N; j ++)
            printf(" %d", mat[k].a[i][j + N]);
        printf("\n");
    }
}
int main()
{
    while(scanf("%d%d%d", &N, &K, &M) == 3)
    {
        init();
        solve();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/staginner/p/2466384.html