首页 > 其他分享 >矩阵相关

矩阵相关

时间:2024-01-26 09:33:57浏览次数:23  
标签:begin end mat int 矩阵 bmatrix 相关

矩阵相关运算

结构体定义

typedef long long ll;
const int N = 110;
int n, mod;

struct Mat {
	int n, m; //矩阵的行和列
    int a[N][N];
	void zero() { //0矩阵 
		memset(a, 0, sizeof(a));
	}
	void one() { //n*n的单位矩阵 
		zero();
		for (int i = 1; i <= n; i++) a[i][i] = 1;
	}
	void resize(int x, int y) { //设置矩阵大小 
		n = x; m = y;
	}
	//矩阵加,第二个const表示不能修改成员变量的值,对数据起到保护作用,下同
	Mat operator +(const Mat &A) const {
		Mat res;
		res.resize(n, A.m);
		
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				res.a[i][j] = (a[i][j] + A.a[i][j]) % mod; 
			}
		}
		return res;
	}
	
	//矩阵减 
	Mat operator -(const Mat &A) const {
		Mat res;
		res.resize(n, A.m);
		
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				res.a[i][j] = (a[i][j] - A.a[i][j]) % mod; 
			}
		}
		return res;
	}
	
	//矩阵乘 
	Mat operator *(const Mat &A) const {
		Mat res;
		res.resize(n, A.m);
		res.zero();
		
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= A.m; j++) {
				for (int k = 1; k <= m; k++) {
					res.a[i][j] = ((ll)a[i][k] * A.a[k][j] + res.a[i][j]) % mod;
				}
			}
		}
		return res;
	}
	//输出矩阵 
	void ouput() {
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				printf("%d ", a[i][j]);
			}
			putchar('\n');
		}
	}
};

矩阵快速幂

可以利用上面定义好的结构,方便写出矩阵快速幂的形式。

例 1:计算斐波那契数

【问题描述】

计算斐波那契数列的第 \(n\) 项 \(F_n\)(\(1\le n\le 2\times 10^9\))。

【分析】

根据斐波那契数列的递推式 \(F_n = F_{n-1} + F_{n-2}\),我们可以构建一个 \(2\times 2\) 的矩阵来表示从 \(F_n,F_{n+1}\) 到 \(F_{n+1},F_{n+2}\) 的变换。于是在计算这个矩阵的 \(n\) 次幂的时侯,我们使用快速幂的思想,可以在 \(\Theta(\log n)\) 的时间内计算出结果。

根据斐波那契数列 递推公式的矩阵形式:

\[\begin{bmatrix} F_{n-1} & F_{n-2} \end{bmatrix} \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix} = \begin{bmatrix} F_n & F_{n-1} \end{bmatrix} \]

我们定义初始矩阵

\[\begin{bmatrix}F_2 & F_1\end{bmatrix} = \begin{bmatrix}1 & 1\end{bmatrix}, \text{base} = \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix} \]

那么,

\[\text{ans}=\begin{bmatrix}F_2 & F_1\end{bmatrix}\times\text{base}^{n-2} \]

则 \(F_n\) 就等于 \(ans\) 矩阵的第一行第一列元素。

为什么要乘上 \(\text{base}\) 矩阵的 \(n-2\) 次方而不是 \(n\) 次方呢?因为 \(F_1, F_2\) 是不需要进行矩阵乘法就能求的。也就是说,如果只进行一次乘法,就已经求出 \(F_3\) 了,手算一下就能理解了。

【示例代码】

//矩阵快速幂 
Mat qpow(Mat A, int b) {
	Mat res;
	res.resize(2, 2);
	res.one();
	while (b) {
		if (b & 1) {
			res = res * A;
		}
		A = A * A;
		b >>= 1;
	}
	return res;
}

int main() {
	Mat mat;
	scanf("%d%d", &n, &mod);
	//初始化矩阵 
	mat.resize(2, 2);
	mat.a[1][1] = mat.a[1][2] = mat.a[2][1] = 1;
	mat.a[2][2] = 0;
	
	mat = qpow(mat, n-2);
	int ans = (mat.a[1][1] + mat.a[2][1]) % mod;
	printf("%d\n", ans);
	return 0;
}

标签:begin,end,mat,int,矩阵,bmatrix,相关
From: https://www.cnblogs.com/kuangbiaopilihu/p/17988622

相关文章

  • WebGL之二维矩阵变换(高级)
    一,index.html<body> <scriptsrc="js/common/shaderUtil.js"></script> <scriptid="vertex-shader-2d"type="notjs"> attributevec2a_position; attributevec2a_texCoord; uniformmat3u_matrix;//2D变......
  • 算法随记_1 蛇形矩阵(偏移量法)
    蛇形矩阵title:(在线学习平台)link:(https://www.acwing.com/)cover:(https://cdn.acwing.com/media/activity/surface/log.png)输入两个整数n和m,输出一个n行m列的矩阵,将数字1到n×m按照回字蛇形填充至矩阵中。具体矩阵形式可参考样例。输入样例33输出样例12......
  • (2/60)有序数组平方、长度最小子数组、螺旋矩阵
    有序数组的平方leetcode:977.有序数组的平方给你一个按非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。暴力法思路遍历数组,元素原地替换为自身平方值。将数组进行排序。复杂度分析时间复杂度:O(N+logN)空间复杂度:O(1)注......
  • 代码随想录算法训练营第二天|977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
    977.有序数组的平方给你一个按非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/错误的vector遍历方式,这会导致访问越界!!!while(nums[flag]<0)flag++;倒也不难,我......
  • 矩阵号:日入100+,八大提示词(Prompt)使用技巧
    最近在搞头条矩阵,发现自己的指令写的太烂了,一个指令将会决定你的写作质量。收益比较拉垮,50个号收益好的,也就这么几个号。于是我扒了一些提示词的操作技巧,分享一下自己的学习心得。先说理论知识,实操放文章最后。我们与GPT沟通交流时,可以用到乔哈里()沟通视窗模型,它分为......
  • 开发者工具相关
    打开开发者工具快捷方式:Windows/Linux:Ctrl+Shift+I或F12Mac:Cmd+Option+I基本界面和功能1.元素面板(Elements)这是你可以查看、编辑和调试网页内容的地方。   检查元素:右键任何网页元素>检查,或使用工具上的小放大镜图标。这将突出显示元素并在元素面......
  • 一些C++相关的网站
     https://cppinsights.io/ cppinsights.io是一个在线C++代码查看工具,它可以帮助你深入了解C++代码在编译器层面的实际情况。该工具的主要功能是展示C++代码的编译器输出,即展示编译器对代码进行优化、展开模板、内联函数等操作后的实际代码。 https://zh.cpprefere......
  • P1962 斐波那契数列(矩阵快速幂)
    #include<bits/stdc++.h> #defineintlonglong usingnamespacestd; intn,a[3],m=1e9+7,c[3][3],b[3][3],x[3][3],a1[3]; voidfirst() { for(inti=1;i<=2;i++) for(intj=1;j<=2;j++)x[i][j]=0; for(inti=1;i<=2;i++) ......
  • 从CF1819A学习mex相关问题及assert调试宏
    Problem-1819A-Codeforces快速计算mexintcalcMex(vector<int>v){ sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()) intn=int(v.size());for(inti=0;i<n;++i)if(v[i]!=i)returni;returnn;}<cass......
  • Promise相关
    Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。Promise是一个ECMAScript6提供的类,目的是更加优雅地书写复杂的异步任务。Promise是一个构造函数,通过......