UVa 10870 - Recurrences 矩阵快速幂

构造矩阵.

见《训练指南》p156...

#include <cstdio>

#include <cstring>

#include <cstdlib>



#define LL long long int



using namespace std;



const int MAXN = 20;



LL mod;



struct Matrix

{

    LL a[MAXN][MAXN];

    int r, c;

    friend Matrix operator*( Matrix &a, Matrix &b );

    friend Matrix operator^( Matrix a, LL k );

};



Matrix operator*( Matrix &a, Matrix &b )

{

    Matrix tmp;

    tmp.r = a.r;

    tmp.c = b.c;

    for ( int i = 1; i <= a.r; ++i )

        for ( int j = 1; j <= b.c; ++j )

        {

            tmp.a[i][j] = 0;

            for ( int k = 1; k <= a.c; ++k )

            {

                //printf( "%d %d %d\n", i, j, k );

                tmp.a[i][j] = ( tmp.a[i][j] + (a.a[i][k] * b.a[k][j]) % mod ) % mod;

            }

        }

    return tmp;

}



Matrix operator^( Matrix a, LL k )

{

    Matrix unit;

    unit.r = a.r;

    unit.c = a.c;

    memset( unit.a, 0, sizeof(unit.a) );

    for ( int i = 0; i < MAXN; ++i )

        unit.a[i][i] = 1;



    while ( k )

    {

        if ( k & 1 ) unit = unit * a;

        a = a * a;

        k = ( k >> 1 );

    }

    return unit;

}



/**************以上矩阵快速幂模板*****************/



int n, d;

Matrix A, F;



int main()

{

    //freopen( "in.txt", "r", stdin );

    while ( scanf( "%d%d%lld", &d, &n, &mod ), d || n || mod )

    {

        memset( A.a, 0, sizeof(A.a) );

        for ( int i = 1; i < d; ++i )

            A.a[i][i + 1] = 1;



        for ( int i = d; i > 0; --i )

        {

            scanf( "%lld", &A.a[d][i] );

            A.a[d][i] %= mod;

        }

        A.r = d, A.c = d;



        memset( F.a, 0, sizeof(F.a) );

        for ( int i = 1; i <= d; ++i )

        {

            scanf( "%lld", &F.a[i][1] );

            F.a[i][1] %= mod;

        }

        F.r = d, F.c = 1;



        A = A ^ (n - d);

        F = A * F;

        printf( "%lld\n", F.a[d][1] % mod );



    }

    return 0;

}

 

你可能感兴趣的:(uva)