LightOj 1006(矩阵快速幂)

来源:互联网 发布:php删除数据库指定元素 编辑:程序博客网 时间:2024/06/05 15:59

链接:

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 6using 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;}
0 0
原创粉丝点击