LightOj 1131 Just Two Functions

/**

*   Author: johnsondu

*   Time: 2013-5-5

*   Problem: LightOj 1131 Just Two Functions

*   Url:  http://www.lightoj.com/volume_showproblem.php?problem=1131

*   Stratege: Matrix

*      s[N][N] = {a1, b1, 0, 0, 0, c1,

*                 1, 0, 0, 0, 0, 0,

*                 0, 1, 0, 0, 0, 0,

*                 0, 0, c2, a2, b2, 0,

*                 0, 0, 0, 1, 0, 0,

*                 0, 0, 0, 0, 1, 0} ;

*

**/



#include <iostream>

#include <cstdio>

#include <cmath>

#include <algorithm>

#include <cstring>

using  namespace std ;



#define N 6

#define ll long long

ll a1, b1, c1, a2, b2, c2 ;

ll g[3], f[3] ;

ll M, Q, n ;



struct Node

{

    ll mat[N][N] ;

}unit, init ;



void Init ()

{

    scanf ("%lld%lld%lld", &a1, &b1, &c1) ;

    scanf ("%lld%lld%lld", &a2, &b2, &c2) ;

    scanf ("%lld%lld%lld", &f[0], &f[1], &f[2]) ;

    scanf ("%lld%lld%lld", &g[0], &g[1], &g[2]) ;

    scanf ("%lld", &M) ;

    scanf ("%lld", &Q) ;



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

    memset (init.mat, 0, sizeof (init)) ;

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

        unit.mat[i][i] = 1ll ;

    init.mat[0][0] = a1%M, init.mat[0][1] = b1%M, init.mat[0][5] = c1%M ;

    init.mat[3][2] = c2%M, init.mat[3][3] = a2%M, init.mat[3][4] = b2%M ;

    init.mat[1][0] = init.mat[2][1] = init.mat[4][3] = init.mat[5][4] = 1ll ;



}



Node mul (Node a, Node b)

{

    Node c ;

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

        for (int j = 0; j < N; j ++)

        {

            c.mat[i][j] = 0 ;

            for (int k = 0; k < N; k ++)

                c.mat[i][j] += (ll)a.mat[i][k] * b.mat[k][j], c.mat[i][j] %= M ;

        }

    return c ;

}



void MatrixPow (ll p)

{

    Node res = unit, tp = init ;

    while (p)

    {

        if (p & 1)

        {

            res = mul (res, tp) ;

            p -- ;

            continue ;

        }

        tp = mul (tp, tp) ;

        p >>= 1 ;

    }

    //printf ("--\n") ;

    ll resf = 0, resg = 0;

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

    {

        resf += res.mat[0][i] * f[2-i] ;

        resg += res.mat[3][i] * f[2-i] ;

    }

    for (int i = 3; i < N; i ++)

    {

        resf += res.mat[0][i] * g[5-i] ;

        resg += res.mat[3][i] * g[5-i] ;

    }

    printf ("%lld %lld\n", resf%M, resg%M) ;

}



int main ()

{

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

    int tcase, cs = 1 ;

    scanf ("%d", &tcase) ;

    while (tcase --)

    {

        Init () ;

        printf ("Case %d:\n", cs ++) ;

        while (Q --)

        {

            scanf ("%lld", &n) ;

            if (n < 3)

                printf ("%lld %lld\n", f[n] % M, g[n] % M) ;

            else MatrixPow (n-2) ;

        }

    }

    return 0 ;

}


你可能感兴趣的:(functions)