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.


解题思路:


只要遇到“把一个向量V变成另一个向量V',并且V'的每一个分量都是V各个分量的线性组合”的情况,就可以考虑用矩阵乘法来描述这个关系。



线性方程组:Ax = b,关键是构造矩阵A。

此题线性方程组如下:

hdu1757 A Simple Math Problem(矩阵乘法)_第1张图片



hdu1757 A Simple Math Problem(矩阵乘法)_第2张图片


接下来就是计算了A^n了

矩阵的幂:


对于矩阵的幂可以采用二分快速幂


My_Code:

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

typedef long long LL;
const int N = 10;
LL k, m;

struct mtx
{
    LL x[N+1][N+1];
    mtx() {
        memset(x, 0, sizeof x );
    }
};

mtx operator *(const mtx &a, const mtx &b)
{
    mtx c;
    for(int i=0; i<N; ++i)
    {
        for(int j=0; j<N; ++j)
        {
            for(int k=0; k<N; ++k)
                c.x[i][j] = (c.x[i][j] + a.x[i][k] * b.x[k][j]) % m;
        }
    }
    return c;
}
mtx operator ^(mtx a, LL n)
{
    mtx ret;
    for(int i=0; i<N; ++i) ret.x[i][i] = 1;
    for(; n; n >>= 1)
    {
        if(n&1) ret = ret * a;
        a = a * a;
    }
    return ret;
}

int main()
{
    int i;
    LL sum;
    mtx tmp;
    for(i=1; i<N; ++i) tmp.x[i][i-1] = 1;
   // freopen("d:\\in.txt","r",stdin);
    while(cin>>k>>m)
    {
        for(i=0; i<N; ++i) 
               cin>>tmp.x[0][i];
        mtx ans = tmp ^ (k-9);
        sum = 0;
        for(i=0; i<N; ++i)
            sum = (sum + ans.x[0][i]*(N-1-i)) % m;
        cout<<sum<<endl;
    }
}



你可能感兴趣的:(hdu1757 A Simple Math Problem(矩阵乘法))