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。
此题线性方程组如下:
接下来就是计算了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;
}
}