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
这道题的矩阵推导
可以参考下图来理解
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<cmath>
const int maxn=1e5+5;
typedef long long ll;
using namespace std;
int n;
int mod;
int len=10;
struct node {
int mat[15][15];//定义矩阵
}x,y;
void init(){//初始化
memset(x.mat ,0,sizeof(x.mat));
for(int i=1;i<len;i++){
x.mat[i][i-1]=1;
}
memset(y.mat ,0,sizeof(y.mat ));
for(int i=0;i<len;i++){
y.mat [i][i]=1;//定义单位矩阵
}
}
node mul(node x,node y){//矩阵乘法
node tmp;
for(int i=0;i<len;i++){
for(int j=0;j<len;j++){
tmp.mat [i][j]=0;
for(int k=0;k<len;k++){
tmp.mat [i][j]+=(x.mat [i][k]*y.mat [k][j])%mod;
}
tmp.mat [i][j]=tmp.mat[i][j]%mod;
}
}
return tmp;
}
node matpow(node x,node y,int num){//矩阵快速幂
while(num){
if(num&1){
y=mul(y,x);
}
x=mul(x,x);
num=num>>1;
}
return y;
}
int main(){
while(~scanf("%d%d",&n,&mod)){
init();
for(int i=0;i<len;i++){
scanf("%d",&x.mat [0][i]);//输入 x 矩阵的第一行
}
if(n<10){
printf("%d\n",n%mod);
}
else{
struct node cnt=matpow(x,y,n-9);
int ans=0;
for(int i=0;i<len;i++){
ans+=(cnt.mat [0][i]*(9-i))%mod;//最后求的是F(n)所以只需要求第一个位置的值就可以
ans=ans%mod;
}
printf("%d\n",ans);
}
}
return 0;
}