原博客地址:https://blog.csdn.net/qq_16554583/article/details/80182429
首先你要会矩阵相乘!!!(不会的话自己百度
矩阵相乘满足结合律(A*B)*C = A*(B*C)
让原矩阵R乘加速矩阵base的n次方
由此可以与数的快速幂结合
就是矩阵快速幂。
矩阵快速幂的关键是构造。
只要能够构造出原矩阵和基数矩阵,题就解了。
构造时根据递推公式,一步一步推出加速矩阵。
下面给三道矩阵快速幂的题,也算是裸题了,代码也都可以当模板用
51Nod 1242 斐波那契数列的第N项:
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1000000009;
struct matrix {
long long coo[2][2];
} r,base;
matrix mult(matrix A,matrix B) { //矩阵相乘
matrix C;
for(int i=0; i<2; i++) {
for(int j=0; j<2; j++) {
C.coo[i][j] = 0;
for(int k=0; k<2; k++) {
C.coo[i][j] += (A.coo[i][k]*B.coo[k][j]) % MOD;
}
C.coo[i][j] %= MOD;
}
}
return C;
}
int Pow(long long n) {
base.coo[0][0] = base.coo[0][1] = base.coo[1][0] = 1; //加速矩阵
base.coo[1][1] = 0;
r.coo[0][0] = r.coo[1][1] = 1; //单位矩阵
r.coo[0][1] = r.coo[1][0] = 0;
while(n) { //矩阵快速幂
if(n & 1)
r = mult(r,base);
base = mult(base,base);
n >>= 1;
}
return r.coo[0][1];
}
int main() {
long long n;
scanf("%lld",&n);
long long res = Pow(n);
printf("%lld\n",res);
return 0;
}
Fibonacci数列(二):
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define Mod 10000
using namespace std;
struct node{
int matrix[2][2];
} base,R;
node matrixmul(node A,node B) {
node C;
for(int i=0; i<2; i++) {
for(int j=0; j<2; j++) {
C.matrix[i][j] = 0;
for(int k=0; k<2; k++){
C.matrix[i][j] += (A.matrix[i][k] * B.matrix[k][j]) % Mod;
C.matrix[i][j] %= Mod;
}
}
}
return C;
}
int Pow(int n) {
base.matrix[0][0] = base.matrix[0][1] = base.matrix[1][0] = 1;
base.matrix[1][1] = 0;
R.matrix[0][0] = R.matrix[0][1] = R.matrix[1][0] = 1;
R.matrix[1][1] = 0;
while(n) {
if(n & 1)
R = matrixmul(R,base);
base = matrixmul(base,base);
n >>= 1;
}
return R.matrix[0][1] % Mod;
}
int main() {
int n;
while(scanf("%d",&n),n != -1) {
if(n == 0)
printf("0\n");
else
printf("%d\n",Pow(n-1));
}
return 0;
}
递推求值:
#include <bits/stdc++.h>
#define Mod 1000007
using namespace std;
typedef long long ll;
ll a,b,c,n;
struct matrix {
ll coo[3][3];
} R,base;
matrix mult(matrix A,matrix B) {
matrix C;
for(int i=0; i<3; i++) {
for(int j=0; j<3; j++) {
C.coo[i][j] = 0;
for(int k=0; k<3; k++) {
C.coo[i][j] += (A.coo[i][k] * B.coo[k][j] + Mod) % Mod;
C.coo[i][j] = (C.coo[i][j] + Mod) % Mod;
}
}
}
return C;
}
matrix Pow(matrix base,ll n) {
matrix r = {
1,0,0,
0,1,0,
0,0,1
};
while(n) {
if(n & 1)
r = mult(r,base);
base = mult(base,base);
n >>= 1;
}
return r;
}
int main() {
ll t;
ll f1,f2;
scanf("%lld",&t);
while(t--) {
scanf("%lld%lld%lld%lld%lld%lld",&f1,&f2,&a,&b,&c,&n);
if(n == 0)
printf("%d\n",(f2-f1*b-c+Mod)%Mod);
if(n == 1)
printf("%d\n",(f1+Mod)%Mod);
else if(n == 2)
printf("%d\n",(f2+Mod)%Mod);
else {
memset(R.coo,0,sizeof(R.coo));
R.coo[0][0] = f2;
R.coo[0][1] = f1;
R.coo[0][2] = 1;
matrix base= {
0,1,0,
0,0,0,
0,0,1
};
base.coo[0][0] = b;
base.coo[1][0] = a;
base.coo[2][0] = c;
base = Pow(base,n-2);
R = mult(R,base);
printf("%lld\n",(R.coo[0][0] + Mod)% Mod);
}
}
return 0;
}