LightOj 1006(矩陣快速冪)

鏈接:

lightoj

題目大意:

求遞推式:

f(n)=i=16f(ni)

解題思路:

矩陣快速冪:

f(0)f(1)f(2)f(3)f(4)f(5)000001100001010001001001000101000011n5

實現:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define LL long long
#define MOD 10000007
#define N 6

using namespace std;

struct Matrix
{
    LL m[N][N];
}init;

Matrix Mult(Matrix m1, Matrix m2)
{
    Matrix ans;

    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            ans.m[i][j] = 0;

            for (int k = 0; k < N; k++)
            {
                ans.m[i][j] = (ans.m[i][j] + m1.m[i][k] * m2.m[k][j] % MOD) % MOD;            
            }
        }
    }

    return ans;
}

Matrix Pow(Matrix m, int b)
{
    Matrix ans;

    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            ans.m[i][j] = (i == j);
        }
    }

    while (b)
    {
        if (b & 1)
        {
            ans = Mult(ans, m);
        }

        m = Mult(m, m);
        b >>= 1;
    }

    return ans;
}

void init_mat()
{
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 6; j++)
        {
            init.m[i][j] = 0;
        }
    }
    for (int i = 0; i < 6; i++)
    {
        init.m[5][i] = 1;
    }

    init.m[0][1] = init.m[1][2] = init.m[2][3] = init.m[3][4] = init.m[4][5] = 1;
}

int main()
{
    int T;
    scanf("%d", &T);

    for (int cas = 1; cas <= T; cas++)
    {
        LL a[10];
        for (int i = 0; i < 6; i++)
        {
            scanf("%lld", &a[i]);
            a[i] = a[i] % MOD;    //MOD < 2^31 - 1, WA3發;
        }

        int n;
        scanf("%d", &n);

        printf("Case %d: ", cas);

        if (n < 6)
        {
            printf("%lld\n", a[n]);
        }
        else
        {
            init_mat();

            init = Pow(init, n - 5);

            LL ans = 0;

            for (int i = 0; i < 6; i++)
            {
                ans = (ans + init.m[5][i] * a[i] % MOD) % MOD;
            }

            printf("%lld\n", ans);
        }
    }

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章