矩阵快速幂用于解决快速求线性递推关系f(n) = a1*f(n-1) + a2*f(n-2) + a3*f(n-3) + ...+ ad*f(n-d)中的项f(n);
具体方法;
令F(n) = [ f(n-d+1), f(n-d+2),,,,,,f(n)]; //注意此处F(n)看做d行1列的矩阵
则可以构造一个矩阵c[d][d],使得F(n) = c*F(n-1);
那么F(n) = c^(n-d)*F(d);
其中a的构造方法为:
memset(c,0,sizeof(c));
for (int i=0; i<d-1; i++){
c[i][i+1] = 1;
}
for (int i=d-1,j = 0; i >=0; i--,j++) c[d-1][i] = a[j];
矩阵快速幂模板:
void mul_Matrix(int X[MAX][MAX], int Y[MAX][MAX], int d){ //矩阵乘法 ,计算矩阵X和Y的成绩,并将结果存在X中
int res[MAX][MAX];
memset(res,0,sizeof(res));
for (int i=0; i<d; i++){
for (int j=0; j<d; j++){
int t = 0;
for (int k=0; k<d; k++){
res[i][j] = (res[i][j] + X[i][k]*Y[k][j] % MOD) % MOD;
}
}
}
memcpy(X,res,sizeof(res));
}
void pow_Matrix(int c[MAX][MAX], int d, int n){ //矩阵快速幂 ,计算c^n,并将结果存在c中
int u[MAX][MAX], v[MAX][MAX];
memset(u,0,sizeof(u));
memcpy(v,c,sizeof(v));
for (int i=0; i<d; i++) u[i][i] = 1;
while (n > 0){
if (n & 1) mul_Matrix(u,v,d);
n >>= 1;
mul_Matrix(v,v,d);
}
memcpy(c,u,sizeof(u));
}
矩阵快速幂求
Fibonacci
poj3070
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<string>
#include<stack>
#include<set>
#define ll long long
#define MAX 10
#define INF INT_MAX
#define eps 1e-8
#define MOD 10000
using namespace std;
int a[MAX][MAX],b[MAX][MAX];
void mul_Matrix(int X[MAX][MAX], int Y[MAX][MAX], int d){ //矩阵乘法
int res[MAX][MAX];
memset(res,0,sizeof(res));
for (int i=0; i<d; i++){
for (int j=0; j<d; j++){
int t = 0;
for (int k=0; k<d; k++){
res[i][j] = (res[i][j] + X[i][k]*Y[k][j] % MOD) % MOD;
}
}
}
memcpy(X,res,sizeof(res));
}
void pow_Matrix(int c[MAX][MAX], int d, int n){ //矩阵快速幂
int u[MAX][MAX], v[MAX][MAX];
memset(u,0,sizeof(u));
memcpy(v,c,sizeof(v));
for (int i=0; i<d; i++) u[i][i] = 1;
while (n > 0){
if (n & 1) mul_Matrix(u,v,d);
n >>= 1;
mul_Matrix(v,v,d);
}
memcpy(c,u,sizeof(u));
}
int main(){
int n,c[MAX][MAX];
while (scanf("%d", &n)){
if ( n < 0) break;
//printf("%d\n",n);
c[0][0] = 0;
c[0][1] = c[1][0] = c[1][1] = 1; //根据递推式构造矩阵。思考 ? 如何构造
if (n == 0){
printf("0\n");
continue;
}
if (n == 1){
printf("1\n");
continue;
}
int res[2],f[] = {1,1}; //结果矩阵,最终结果保存在为res[d-1]; 注意此处res[],f[] = {1,1}看做2行1列的矩阵,其中1,1分别为数列的前两项
pow_Matrix(c,2,n-2);
for (int i=0; i<2; i++){
res[i] = 0;
for (int k = 0; k<2; k++) res[i] = (res[i] + c[i][k]*f[k] % MOD) % MOD;
}
printf("%d\n",res[1] % MOD);
}
return 0;
}