hdu1757---A Simple Math Problem(矩阵)

problem Description
Lele now is thinking about a simple function f(x).

If x < 10 f(x) = x.
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
And ai(0<=i<=9) can only be 0 or 1 .

Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.

Input
The problem contains mutiple test cases.Please process to the end of file.
In each case, there will be two lines.
In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 )
In the second line , there are ten integers represent a0 ~ a9.

Output
For each case, output f(k) % m in one line.

Sample Input

10 9999 1 1 1 1 1 1 1 1 1 1 20 500 1 0 1 0 1 0 1 0 1 0

Sample Output

45 104

Author
linle

Source
2007省赛集训队练习赛(6)_linle专场

Recommend
lcy | We have carefully selected several similar problems for you: 1588 3117 2276 2256 2254

很明显的矩阵递推题

/************************************************************************* > File Name: hdu1757.cpp > Author: ALex > Mail: [email protected] > Created Time: 2015年03月11日 星期三 19时57分20秒 ************************************************************************/

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

int mod;

class MARTIX
{
    public:
        int mat[105][105];
        MARTIX();
        MARTIX operator + (const MARTIX &b)const;
        MARTIX operator * (const MARTIX &b)const;
        MARTIX & operator = (const MARTIX &b);
};

MARTIX :: MARTIX()
{
    memset (mat, 0, sizeof(mat));
}

MARTIX MARTIX :: operator + (const MARTIX &b)const
{
    MARTIX ret;
    for (int i = 0; i < 10; ++i)
    {
        for (int j = 0; j < 10; ++j)
        {
            ret.mat[i][j] = mat[i][j] + b.mat[i][j];
            ret.mat[i][j] %= mod;
        }
    }
    return ret;
}

MARTIX MARTIX :: operator * (const MARTIX &b)const
{
    MARTIX ret;
    for (int i = 0; i < 10; ++i)
    {
        for (int j = 0; j < 10; ++j)
        {
            ret.mat[i][j] = 0;
            for (int k = 0; k < 10; ++k)
            {
                ret.mat[i][j] += mat[i][k] * b.mat[k][j];
                ret.mat[i][j] %= mod;
            }
        }
    }
    return ret;
}

MARTIX & MARTIX :: operator = (const MARTIX  &b)
{
    for (int i = 0; i < 10; ++i)
    {
        for (int j = 0; j < 10; ++j)
        {
            this -> mat[i][j] = b.mat[i][j];
        }
    }
    return *this;
}

MARTIX fastpow(MARTIX A, LL n)
{
    MARTIX ans;
    for (int i = 0; i < 10; ++i)
    {
        for (int j = 0; j < 10; ++j)
        {
            ans.mat[i][j] = (i == j);
        }
    }
    while (n)
    {
        if (n & 1)
        {
            ans = ans * A;
        }
        n >>= 1;
        A = A * A;
    }
    return ans;
}

void Debug(MARTIX A)
{
    for (int i = 0; i < 10; ++i)
    {
        for (int j = 0; j < 10; ++j)
        {
            printf("%d ", A.mat[i][j]);
        }
        printf("\n");
    }
}

int main ()
{
    LL k;
    while (~scanf("%lld%d", &k, &mod))
    {
        if (k < 10)
        {
            printf("%lld\n", k);
            continue;
        }
        MARTIX A;
        for (int i = 0; i < 10; ++i)
        {
            scanf("%d", &A.mat[i][0]);
        }
        for (int i = 0; i < 9; ++i)
        {
            A.mat[i][i + 1] = 1;
        }
        MARTIX ans = fastpow(A, k - 9);
        MARTIX F;
        for (int i = 0; i < 10; ++i)
        {
            F.mat[0][i] = 10 - i - 1;
        }
// Debug(F);
        ans = F * ans;
        printf("%d\n", ans.mat[0][0]);
    }
    return 0;
}

你可能感兴趣的:(矩阵)