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

  

posted @ 2015-07-20 19:35  豪气干云  阅读(153)  评论(0编辑  收藏  举报