矩阵快速幂

核能气质少年 提交于 2020-04-06 19:30:42

矩阵快速幂

\(emmm\),考试上面见到的,以前听颜神讲过一遍但是没有听懂,现在看一下还是比较妙妙的

矩阵乘法

矩阵乘法是什么?

简而言之就是

\[c_{ij} = \quad\sum_{k=1}^na_{ik} *b_{kj} \]

举个简单的例子

\[\left\{ \begin{matrix} 14 \\ 32 \\ 50 \end{matrix} \right\} = \left\{ \begin{matrix} 1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9 \end{matrix} \right\} * \left\{ \begin{matrix} 1\\ 2 \\ 3 \end{matrix} \right\} \]

真简单哇!(光速溜

\(emmm\),这就是矩阵乘法的定义

下面给出详细代码

int n;//矩阵大小

void Up(int &x, int y) { x = (x + y) % mod; }//简单定义 += 

struct Matrix
{
	int a[n][n];//矩阵
	friend Matrix operator *(const Matrix x, const Matrix y)//定义矩阵类型的乘法
	{
		Matrix c;//定义新的矩阵用来存储结果
		memset(c.a, 0, sizeof(c.a));//初始化
		for(int i = 0; i < n;i ++)//进行枚举
			for(int j = 0; j < n;j ++)
				for(int k = 0; k < n;k ++)
					Up(c.a[i][j], x.a[i][k] * y.a[k][j] % mod);//相乘 
		return c;//返回答案矩阵
	}
};

快速幂

快速幂还算比较简单了的吧

反正我一开始只是知道快速幂而已

简单来说,通过二进制位来实现

\(2^0= 2^0\)

\(2^1 = 2^1\)

\(2^2=2^2\)

\(2^3 = 2^2*2\)

\(2^4 =2^4\)

\(2^5 = 2^4*2\)

\(2^6 = 2 ^ 4 * 2 ^ 2\)

\(2^7 = 2^4*2^2*2\)

所以我们可以看出来的是

二进制位上我们现在只有当某一位是1的时候才乘

举个例子

\[2^{15} =2^{1111} = 2^{1000}*2^{100}*2^{10}*2^{1}=2^8*2^4*2^2*2^1 \]

所以相对来说比较好理解

原来\(O(b)\)复杂度一下降低到了\(O(logb)\)

所以快速幂是一种优化的手段

下面贴上代码

inline int pow(int a,int b)
{
    int r=1,base=a;
    while(b)
    {
        if(b&1) r*=base;//如果当前位是1,那么直接相乘
        base*=base;//不管是什么数字下一位都需要再乘一次(2的倍数)
        b>>=1;//移到下一位
    }
    return r;//返回结果
}

矩阵乘法快速幂

void Up(int &x, int y) { x = (x + y) % mod; }//简单定义+=

struct Matrix
{
	int a[n][n];
	friend Matrix operator *(const Matrix x, const Matrix y)//定义矩阵乘法
	{
		Matrix c;
		memset(c.a, 0, sizeof(c.a));
		for(int i = 0; i < n; i ++)
			for(int j = 0; j < n; j ++)
				for(int k = 0; k < n; k ++)
					Up(c.a[i][j], x.a[i][k] * y.a[k][j] % mod); 
		return c;
	}
};

Matrix Qpow(Matrix x, int timer)//矩阵快速幂
{
	Matrix base;//定义结果矩阵
	for(int i = 0; i < n; i ++)
		for(int j = 0; j < n; j ++)
			base.a[i][j] = 0;
	for(int i = 0; i < n; i ++) base.a[i][i] = 1;
	for(; timer; timer >>= 1, x = x * x)
		if(timer & 1) base = base * x;
	return base;
}

\(mod\)是一个简单的模数,考试的时候一般要求取模运算

Luogu P1962 斐波那契数列

\(emmm\)可以说是矩阵快速幂的基础练习题

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!