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 ;
}


posted @ 2013-05-04 20:18  xinyuyuanm  阅读(247)  评论(0编辑  收藏  举报