快速幂与矩阵快速幂学习笔记

1.“取模”运算法则

1. ( a + b ) % c = ( ( a % c ) + ( b % c ) ) % c

2. ( a * b ) % c = ( ( a % c ) * ( b % c ) ) % c

3. ( a – b ) % c = ( ( a % c ) – ( b % c ) ) % c

2.位运算

判断奇偶
x%2==1可以使用x&1==1代替,x%2==0可以使用x&1==0代替

x=x/2可以使用x>>=1代替,意为把x的二进制向右移动1位
x=x*2可以使用x<<=1代替,意为把x的二进制向左移动1位
PS:如果是x>>=y,意为x=x/(2^y)

3.大佬的快速幂最终模板

long long fastPower(long long base, long long power) {//base为底数,power为指数
    long long result = 1;
    while (power > 0) {
        if (power & 1) {//此处等价于if(power%2==1)
            result = result * base % 1000;//%1000是取结果的后三位,根据题目要求变化
        }
        power >>= 1;//此处等价于power=power/2
        base = (base * base) % 1000;
    }
    return result;
}
  • 矩阵快速幂
    首先就是要了解矩阵,单位矩阵,矩阵加减法,矩阵乘法

矩阵定义:由 m × n 个数aij排成的m行n列的数表称为m行n列的矩阵,简称m × n矩阵。记作:
Alt

矩阵加减法:只有同型矩阵之间才可以进行加减法
减法:
在这里插入图片描述

单位矩阵:在矩阵的乘法中,有一种矩阵起着特殊的作用,如同数的乘法中的1,这种矩阵被称为单位矩阵。它是个方阵,从左上角到右下角的对角线(称为主对角线)上的元素均为1。除此以外全都为0。
在这里插入图片描述

矩阵乘法:两个矩阵的乘法仅当第一个矩阵A的列数和另一个矩阵B的行数相等时才能定义。如A是m×n矩阵和B是n×p矩阵,它们的乘积C是一个m×p矩阵
例如:
在这里插入图片描述
深入了解矩阵乘法:https://blog.csdn.net/zh_94/article/details/81571092

PS:在写矩阵快速幂的题目时,一般是做A(nxn)^m这样的运算,求nxn的矩阵A的m次幂,例如:

	  [1 2 3]
	A=[4 5 6] 
	  [7 8 9]
	  
	A是一个3x3的矩阵,求A^2,即
	
	[1 2 3]   [1 2 3]		[C11 C12 C13]
	[4 5 6]	x [4 5 6] =C矩阵[C21 C22 C23] 
	[7 8 9]   [7 8 9]		[C31 C32 C33]
	
	由于我们一般使用二维数组储存矩阵A,计算时也会是一个点一个点的去求解
	求解法则:第1个矩阵A当前点的行x第2个矩阵A当前点的列
	例如:C21=(4 5 6)*(1 4 7)
			=4*1+5*4+6*7
			=66 
  • 矩阵快速幂应用:
    一般题目会给出一个递推式,如:
f(n)=a1*f(n-1)+a2*f(n-2)+a3*f(n-3);

给出a1,a2,a3,f1,f2,f3的值,让你求解f(n)%m
首先要把普通递推式变为矩阵递推式,即
先把普通递推式变为矩阵,然后找到一个矩阵A,使左边矩阵*A能变为左边矩阵的下一个状态,如下

【f(n-1),f(n-2),f(n-3)】*A=【f(n),f(n-1),f(n-2)】
可变为
【f(n-1),f(n-2),f(n-3)】*A=【a1*f(n-1)+a2*f(n-2)+a3*f(n-3),f(n-1),f(n-2)】

然后构建一个3x3得矩阵A:
【A11,A12,A13】
【A21,A22,A23】
【A31,A32,A33】

依据矩阵乘法,即可填出矩阵A,为
【a1,1,0】
【a2,0,1】
【a3,0,0】
如此,求f(n)即可变为

S(n)=A^(n-1)*S1
S1为初始矩阵,Sn为最后的矩阵

我们只需做核心的矩阵A的n-1次幂,题目就转化为快速幂算法了

练习题:
http://poj.org/problem?id=3070

#include"iostream"
#include"string.h"
#include"algorithm"
using namespace std;
typedef long long ll;
struct Matrix{
	ll mat[10][10];
}start;

Matrix MUL(Matrix x,Matrix y){
	Matrix z;
	memset(z.mat,0,sizeof(z.mat));
	for(int i=1;i<=2;i++){
		for(int j=1;j<=2;j++){
			for(int k=1;k<=2;k++){
				z.mat[i][j] =(z.mat[i][j] + x.mat[i][k] * y.mat[k][j]%10000)%10000; 
			}
		}
	}
	return z;
}

ll fastpower(Matrix x,ll n){
	Matrix res;
	memset(res.mat,0,sizeof(res.mat));
	for(int i=1;i<=2;i++){//单位矩阵对角线赋值1,其余全为0,单位矩阵相当于数值中的1 
		res.mat[i][i]=1;
	}
	while(n){
		if(n&1){
			res=MUL(x,res);
		}
		x=MUL(x,x);
		n>>=1;
	}
	return res.mat[1][2]%10000;
}
int main()
{
	
	ll w;
	while(cin>>w){
		if(w==-1){
			break;
		}
		start.mat[1][1]=start.mat[1][2]=start.mat[2][1]=1;
		start.mat[2][2]=0;
		cout<<fastpower(start,w)<<endl;
	}
	return 0;
}

矩阵题集:
https://vjudge.net/contest/71746

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值