hdu 1005(矩阵快速幂)

6 篇文章 0 订阅

题目传送门

题目描述的是一个递推,并且没有其他变量与n有关,是一个典型的矩阵快速幂模板题(有多种解法,只提这一种)。

{1,1} * A{A,1}   = {f(n),f(n-1)}

             {B,0}

/**
矩阵快速幂 模板 
**/
#include <algorithm>
#include  <iostream>
#include   <cstring>
#include    <string>
#include    <vector>
#include     <cmath> 
#include     <deque>
#include       <map>


#define For(i,a,b) for(i = a;i < b;i ++)
#define For_(i,a,b) for(i = a;i > b; i --) 
#define Max 100
using namespace std;
typedef long long ll;
int Nnum;//矩阵的大小 ,默认为 Nnum * Nnum,这样很好计算 ,从零开始 
int Mod = 7;//取模的大小 
typedef struct node{//Array 在前,* 的在后 
	ll Array[Max][Max];
	node operator * (node a){
		int i,j,k;
		node ans;
		For(i,0,Nnum+1){
			For(j,0,Nnum+1){
				ans.Array[i][j] = 0;
			}
		}
		For(k,0,Nnum +1){//k 在外面可以剪枝 0 的运算 
			For(i,0,Nnum +1){
				if(Array[i][k] != 0)
				For(j,0,Nnum +1){
					if(a.Array[k][j] != 0){
						ans.Array[i][j] =(ans.Array[i][j] + Array [i][k] * a.Array[k][j] % Mod) % Mod;
					}
				}
			}
		}
		return ans;
	}
	
}Node;

void Print(node a){ // 输出 矩阵 
	int i,j;
	For(i,0,Nnum+1){
		For(j,0,Nnum+1){
			cout<<a.Array[i][j]<<" ";
		}
		cout<<endl;
	}
} 

node Clear(){// 矩阵 初始化
	node a;
	int i,j,k;
	For(i,0,Nnum+1){
		For(j,0,Nnum+1){
			a.Array[i][j] = (i == j);
		}
	}
	return a; 
}

node ArrayQuit(node ans,node a,int N){//快速幂 
	while(N){
		if(N & 1)ans = (ans * a);
		a = (a * a);
		N >>= 1;
		
	} 
	return ans;
} 

/*
1 1 3
1 2 10
0 0 0
 
*/
int main(){
	Nnum = 9;//初始化 Nnum Nnum 是矩阵的规模 
	int i,j,k,n,a,b;
	node Array;
	while(scanf("%d%d%d",&a,&b,&n)==3){
		if(a==0&&b==0&&n==0)break;
		if(n < 3){
			printf("1\n");
			continue;
		}
		Array.Array[0][0] = a,Array.Array[0][1] = 1,Array.Array[1][0] = b,Array.Array[1][1]= 0;
		node ans;
		ans.Array[0][0]=1,ans.Array[0][1] = 1; 
//		Print(ans);
		ans = ArrayQuit(ans,Array,n-2);
//		cout<<"ans:\n";
//		Print(ans);
		printf("%d\n",ans.Array[0][0]);
	}
	
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值