快速幂和矩阵快速幂 数学原理+例题 详解

补充知识

位运算

C语言中的位运算 https://blog.csdn.net/cxyol/article/details/631591

快速幂的数学原理

比如a^156,而156(10)=10011100(2)
在这里插入图片描述
我们就按照这个公式来求解a^156,原来要进行156-1=155次乘法运算,现在的差不多运算次数就是他 二进制的长度二进制中1的个数=84=24次

代码

普通快速幂的模板:

ll pow(ll x, ll y)  //位运算
{
    ll res = 1;
    while(y) {
        if (y&1)  res *= x ;   //res才是最终我们要的结果.
        x *= x ;     //一个中间转移量. y每右移一次, x 就多一个平方.
        y=y>>1;
    }
    return res;
}

矩阵快速幂

构建矩阵乘法

(1)矩阵乘法

在这里插入图片描述
其中c[i][j]为A的第i行与B的第j列对应乘积的和,即
在这里插入图片描述

(2)代码

const int N=100;
int c[N][N];
void multi(int a[][N],int b[][N],int n)//n是矩阵大小,n<N
{
    memset(c,0,sizeof c);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        for(int k=1;k<=n;k++)
        c[i][j]+=a[i][k]*b[k][j];
}

这种可以在第二重for判断if(a[i][k]==0)continue;对于矩阵有较多0的有一定效果。不过一般第一种写法就够了,这种知道就行。
显然矩阵乘法的复杂度是O(n^3);

矩阵快速幂

就是算A^n;方法很简单(A表示矩阵),把快速幂算法中的乘法改成矩阵的乘法就可以了

const int N=10;
int tmp[N][N];
void multi(int a[][N],int b[][N],int n)
{
    memset(tmp,0,sizeof tmp);
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        for(int k=0;k<n;k++)
        tmp[i][j]+=a[i][k]*b[k][j];
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        a[i][j]=tmp[i][j];
}
int res[N][N];
void Pow(int a[][N],int n)
{
    memset(res,0,sizeof res);//n是幂,N是矩阵大小
    for(int i=0;i<N;i++) res[i][i]=1;
    while(n)
    {
        if(n&1)
            multi(res,a,N);//res=res*a;复制直接在multi里面实现了;
        multi(a,a,N);//a=a*a
        n>>=1;
    }
}

上诉res数组就等同于普通快速幂初始化的1,原理相通的,这个矩阵叫单位矩阵E,性质就是EA=A,就是1a=a,一样,单位矩阵就是对角线全是1其他全是0;

也可以利用结构体构建矩阵

struct node {
	int mat[15][15];//定义矩阵 
}x,y; 

node mul(node x,node y){//矩阵乘法 
	node tmp;
	for(int i=0;i<len;i++){
		for(int j=0;j<len;j++){
			tmp.mat [i][j]=0;
			for(int k=0;k<len;k++){
				tmp.mat [i][j]+=(x.mat [i][k]*y.mat [k][j])%mod;
			}
			tmp.mat [i][j]=tmp.mat[i][j]%mod;
		}
	}
	return tmp;
} 

node matpow(node x,node y,int num){//矩阵快速幂 
	while(num){
		if(num&1){
			y=mul(y,x);
		}
		x=mul(x,x);
		num=num>>1;
	}
	return y;
} 

如何构建矩阵

如何构造矩阵:http://www.cnblogs.com/frog112111/archive/2013/05/19/3087648.html
一些递推式:
在这里插入图片描述

例题

1.矩阵的迹 https://blog.csdn.net/forever_kirito/article/details/77141006
2.Fibonacci https://blog.csdn.net/forever_kirito/article/details/77035751
3.模板题 https://blog.csdn.net/red_red_red/article/details/90208456

转自

https://blog.csdn.net/red_red_red/article/details/90208713
https://blog.csdn.net/wust_zzwh/article/details/52058209?utm_medium=distribute.pc_relevant.none-task-blog-title-2&spm=1001.2101.3001.4242

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值