矩阵快速幂

矩阵快速幂用于解决快速求线性递推关系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;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值