类似于快速幂
矩阵快速幂是一个Matrix 的k次方
(|A|^{k}=|A|^{k/2}*|A|^{k/2})
对于这种幂的(自己乘以自己,可以用快速幂来求)
对于任何线性递归式,都可以进行矩阵加速
可以吧O(n)的线性进行转换为O((log_{2}n * C))C 是常数,有题目决定
快速幂
Matrix ksm(Matrix a,int b){
if(b == 0)return a;
Matrix ans(a.n,a.m);
int maxx = max(a.n,a.m);
for(int i = 0; i <= maxx; i++)ans.a[i][i] = 1;
while(b){
if(b & 1)ans = ans * a;
a = a * a;
b >>= 1;
}
return a
矩阵相乘
Matrix operator * (const Matrix &a,const Matrix &b){
Matrix ans(a.n,b.m);
for(int i = 0; i < a.n; i++){
for(int j = 0; j < b.m; j++){
for(int k = 0; k < a.m; k++){
ans.a[i][j] = (ans.a[i][j] + a.a[i][k] * b.a[k][j] % mod) % mod;
}
}
}
return ans;
}
矩阵的定义
struct Matrix{
int n,m;
int a[N][N];
Matrix(int x,int y):n(x),m(y){memset(a,0,sizeof(a));}
};
也可以在矩阵定义中重载
struct Matrix{
int n,m;
int a[11][11];
Matrix(int x,int y):n(x),m(y){memset(a,0,sizeof(a));}
Matrix operator * (const Matrix &b){
Matrix ans(n,b.m);
for(int i = 0; i < n; i++){
for(int j = 0; j < b.m; j++){
for(int k = 0; k < m; k++){
ans.a[i][j] = (ans.a[i][j] + a[i][k] * b.a[k][j] % mod) % mod;
}
}
}
return ans;
}
};
矩阵快速幂
#include <iostream>
#include <cstdio>
#include <algorithm>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define mod 1000000007
#define ll long long
using namespace std;
const int N = 25;
struct Matrix{
int n,m;
int a[11][11];
Matrix(int x,int y):n(x),m(y){memset(a,0,sizeof(a));}
Matrix operator * (const Matrix &b){
Matrix ans(n,b.m);
for(int i = 0; i < n; i++){
for(int j = 0; j < b.m; j++){
for(int k = 0; k < m; k++){
ans.a[i][j] = (ans.a[i][j] + a[i][k] * b.a[k][j] % mod) % mod;
}
}
}
return ans;
}
};
Matrix ksm(Matrix a,int b){
if(b == 0)return a;
Matrix ans(a.n,a.m);
int maxx = max(a.n,a.m);
for(int i = 0; i <= maxx; i++)ans.a[i][i] = 1;
while(b){
if(b & 1)ans = ans * a;
a = a * a;
b >>= 1;
}
return ans;
}
int main(){
return 0;
}
矩阵快速幂进行加速
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 15;
int k,mod;
int a[maxn];
struct Matrix{
int n,m;
int a[11][11];
Matrix(int x,int y):n(x),m(y){memset(a,0,sizeof(a));}
Matrix operator * (const Matrix &b){
Matrix ans(n,b.m);
for(int i = 0; i < n; i++){
for(int j = 0; j < b.m; j++){
for(int k = 0; k < m; k++){
ans.a[i][j] = (ans.a[i][j] + a[i][k] * b.a[k][j] % mod) % mod;
}
}
}
return ans;
}
};
Matrix ksm(Matrix a,int b){
if(b == 0)return a;
Matrix ans(a.n,a.m);
int maxx = max(a.n,a.m);
for(int i = 0; i <= maxx; i++)ans.a[i][i] = 1;
while(b){
if(b & 1)ans = ans * a;
a = a * a;
b >>= 1;
}
return ans;
}
Matrix x(10,10);
int getans(int k){
if(k < 10)return k;
Matrix y(10,10);
y = ksm(x,k - 9);
int ans = 0;
for(int i = 0; i < 10; i++){
ans = (ans + (9 - i) * y.a[0][i] % mod) % mod;
}
return ans;
}
int main(){
while(cin >> k >> mod){
for(int i = 0; i < 10; i++){
scanf("%d",&x.a[0][i]);
}
for(int i = 1; i < 10; i++){
x.a[i][i - 1] = 1;
}
cout << getans(k) << endl;
}
return 0;
}