HDU 1757 A Simple Math Problem(矩阵快速幂)

题目链接:戳我

题目大意:

一个函数 f(x)  当 x < 10 ,f(x) = x;

当 x >= 10 时,f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);

给 k 和 m,求 f(k) % m的值

样例解释:

解题思路:

用矩阵快速幂,建立A 矩阵为 10 * 10的,如下

0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
a[9] a[8] a[7] a[6] a[5] a[4] a[3] a[2] a[1] a[0] 其中a数组为上面公式所对应的a

B矩阵为 10 * 1 的, 如下

[0;1;2;3;4;5;6;7;8;9]

故f(n) 为 An * B 所得矩阵的最后一个元素

代码:

//Author LJH

//www.cnblogs.com/tenlee

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cctype>

#include <cmath>

#include <algorithm>

#include <vector>

#include <queue>

#include <stack>

#include <map>

#define clc(a, b) memset(a, b, sizeof(a))

using namespace std;



const int inf = 0x3f;

const int INF = 0x3f3f3f3f;

const int maxn = 10;

int k, m;



void Init(int a[][maxn], int ans[][maxn])

{

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

    {

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

        {

            a[i][j] = 0;

            if(j-1 == i)

            {

                a[i][j] = 1;

            }

        }

    }

    

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

    {

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

        {

            if(i == j)

                ans[i][j] = 1;

            else 

                ans[i][j] = 0;

        }

    }

}



void matrix_mul(int a[][maxn], int b[][maxn])

{

    int i, j, k;

    int tmp[maxn][maxn] = {0};

    for(i = 0; i < maxn; i++)

    {

        for(j = 0; j < maxn; j++)

        {

            for(k = 0; k < maxn; k++)

            {

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

            }

        }

    }

    for(i = 0; i < maxn; i++)

    {

        for(j = 0; j < maxn; j++)

        {

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

        }

    }

    /*for(int i = 0; i < maxn; i++)

    {

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

            printf("b %d ", a[i][j]);

        puts("");

    }*/

}



int quickPow(int a[maxn][maxn], int b[maxn], int ans[maxn][maxn], int n)

{

    /*for(int i = 0; i < maxn; i++)

    {

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

            printf("%d ", a[i][j]);

        puts("");

    }*/

    while(n)

    {

        if(n & 1) matrix_mul(ans, a);

        matrix_mul(a, a);

        n >>= 1;

    }

    /*for(int i = 0; i < maxn; i++)

    {

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

            printf("%d ", ans[i][j]);

        puts("");

    }*/

    

    int sum = 0;

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

    {

        sum = (sum + i * ans[9][i]) % m;

    }

    return sum % m;

}



void func(int a[][maxn])

{

    int d[50];

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

        d[i] = i;

    for(int i = 10; i <= k; i++)

    {

        d[i] = 0;

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

        {

            d[i] = (d[i] + a[9][j] * d[i-j-1] % m) % m;

        }

        printf("%d#%d ", i, d[i]);

    }

    puts("");

}

int main()

{

    freopen("1.txt", "r", stdin);

    int a[maxn][maxn], b[maxn], ans[maxn][maxn];

    while(~scanf("%d %d\n", &k, &m))

    {

        Init(a, ans);

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

        {

            scanf("%d", &a[9][9-i]);

        }

        //func(a);

        if(k >= 10)

            printf("%d\n", quickPow(a, b, ans, k-9));

        else 

            printf("%d\n", k%m);

    }

    return 0;

}

  

你可能感兴趣的:(simple)