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