2018-5-24
简单的矩阵快速幂问题,重点是如何找到对应关系。
f(10) a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 f(9)
f(9) 1 0 0 0 0 0 0 0 0 0 f(8)
f(8) 0 1 0 0 0 0 0 0 0 0 f(7)
f(7) 0 0 1 0 0 0 0 0 0 0 f(6)
f(6) = 0 0 0 1 0 0 0 0 0 0 * f(5)
f(5) 0 0 0 0 1 0 0 0 0 0 f(4)
f(4) 0 0 0 0 0 1 0 0 0 0 f(3)
f(3) 0 0 0 0 0 0 1 0 0 0 f(2)
f(2) 0 0 0 0 0 0 0 1 0 0 f(1)
f(1) 0 0 0 0 0 0 0 0 1 0 f(0)
#include<iostream>
#include<cstring>
using namespace std;
const int N = 10;
int x[N+1][N+1];
int k,m;
void cal(int p[N+1][N+1],int q[N+1][N+1],int r[N+1][N+1]){
for (int i=0;i<N;i++){
for (int j=0;j<N;j++){
for (int k=0;k<N;k++){
r[i][j]+=p[i][k]*q[k][j];
r[i][j]%=m;
}
}
}
}
void fun(int b){
int res[N+1][N+1],base[N+1][N+1],tmp[N+1][N+1];
memset(res,0,sizeof(res));
for (int i=0;i<N;i++) res[i][i]=1;
memcpy(base,x,sizeof(base));
while (b){
if (b&1==1){
memset(tmp,0,sizeof(tmp));
cal(res,base,tmp);
memcpy(res,tmp,sizeof(res));
}
memset(tmp,0,sizeof(tmp));
cal(base,base,tmp);
memcpy(base,tmp,sizeof(base));
b>>=1;
}
int result=0;
for (int i=0;i<N;i++){
result+=res[0][i]*(N-i-1);
result%=m;
}
cout<<result<<endl;
}
int main(){
while (cin>>k>>m){
memset(x,0,sizeof(x));
for (int i=0;i<N;i++){
cin>>x[0][i];
}
for (int i=1;i<N;i++){
x[i][i-1]=1;
}
if (k<10) cout<<k%m<<endl;
else{
fun(k-9);
}
}
return 0;
}
/*
20 500
1 0 1 0 1 0 1 0 1 0
*/