首页 > 其他分享 >矩阵乘法

矩阵乘法

时间:2024-03-30 20:12:52浏览次数:23  
标签:ch mat int ll 矩阵 read 小点 乘法

佳佳的 Fibonacci
由题可知,我们需要用矩阵乘法求出\(T(n)\)
现在就考虑构造几位维的矩阵,我么知道\(F_n=F_{n-1}+F_{n-2}\)
所以求出\(F_n\)至少需要两个元素,然后\(T_n\)呢,就需要\(nF_{n-1}+nF_{n-2}+T_{n-1}\)

\[\left[ \begin{matrix} T_{n-1} & nF_{n-1} & nF_{n-2} & F_{n-1} & F_{n-2} \\ 1 & 0 & 0 & 0 & 0\\ 1 & 1 & 1 & 0 & 0\\ 1 & 1 & 0 & 0 & 0\\ 0 & 1 & 1 & 1 & 1\\ 0 & 1 & 0 & 1 & 0\\ \end{matrix} \right] \]

代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=10;
ll mod,n;
inline ll read()
{
	ll x=0,f=1;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
inline void write(ll x){
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+48);
}
struct Mat
{
	ll n,m;
	ll a[N][N];
	void zero()
	{
		memset(a,0,sizeof(a));
	}
	void one() { 
		zero();
		for (int i = 1; i <= n; i++) a[i][i] = 1;
	}
	void resize(int x, int y) { 
		n = x; m = y;
	}
	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]=((long long)res.a[i][j]+(ll)a[i][k]*A.a[k][j])%mod;
				}		
			}
		}
		return res;
	}
}mat;
Mat qpow(Mat A, ll b) {
	if(b==-1)
	{
		cout<<1;
		exit(0);
	}
	Mat res;
	res.resize(5, 5);
//	res.one();
	res.a[1][1]=3;
    res.a[1][2]=3;
    res.a[1][3]=3;
    res.a[1][4]=1;
    res.a[1][5]=1;
	while (b) {
	if (b & 1) {
	res = res * A;
	}
	A = A * A;
	b >>= 1;
	}
	return res;
}
int main()
{
//	n=read(),mod=read();
	scanf("%d%d",&n,&mod);
//	Mat mat;
	mat.resize(5,5);
	mat.a[1][1]=mat.a[2][1]=mat.a[2][2]=mat.a[2][3]=mat.a[3][1]=mat.a[3][2]=1;
	mat.a[4][4]=mat.a[4][5]=mat.a[5][4]=mat.a[4][2]=mat.a[4][3]=mat.a[5][2]=1;
	mat.a[3][3]=0;
	mat=qpow(mat,n-2);
//	write(mat.a[1][1]);
//	for (int i = 1; i <= 5; i++)cout<<mat.a[i][i]<<" ";
	printf("%lld ",mat.a[1][1]%mod);
	return 0;
}

迷路
\(f_t[i,j]\)表示从i点到j点花费时间为t的方案数
我们假设边权只有1

\[\sum_{k=1}^nf_1[i,k]*f_{t-1}[k,j] \]

f1就是最初的矩阵啊。
我们1个点建9个小点,只有第1小点可以跨越小点的集合。
那么我们建立第i+1小点到第i小点的w=1的单向边
而要连的两个点1到点2则将小点集合1中的小点1和集合2中的小点w相连。
如下图(只画出了点1到点2经过的路径)
image
image

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100;
int mod=2009,n,t;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
inline void write(int x)
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+48);
}
struct mat
{
	int n,m;
	int a[N][N];
	mat()
	{
		memset(a,0,sizeof(a));
	}
	void clear()
	{
		memset(a,0,sizeof(a));
		for(int i=1;i<=n;i++)a[i][i]=1;
	}
	void resize(int x,int y)
	{
		n=x,m=y;
	}
	mat operator *(const mat &A)const
	{
		mat res;
		res.resize(n,A.n);
//		res.n=A.n;
//		res.c();
//		res.clear();
//		memset(a,0,sizeof(a));
		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]=(res.a[i][j]+(ll)a[i][k]*A.a[k][j])%mod;
				}	
			}		
		}
		return res; 
	}	
};
mat qpow(mat A,int q)
{
	mat res;
	res.resize(9*n,9*n);
//	res.n=A.n;
	res.clear();
	while(q)
	{
		if(q&1)res=res*A;
		A=A*A;
//		q>>=1;
		q/=2;
	}
	return res; 
}

int main()
{
//	n=read(),t=read();
	cin>>n>>t;
	mat rm;
	rm.resize(9*n,9*n);
//	rm.clear();
	int b;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=8;j++)
		{
			rm.a[(i-1)*9+j][(i-1)*9+j+1]=1;
		}
		for(int j=1;j<=n;j++)
		{
			scanf("%1d",&b);
			if(b)
			{
				rm.a[(i-1)*9+b][(j-1)*9+1]=1;
			}
		}
	}
	rm=qpow(rm,t);
	printf("%d",rm.a[1][9*n-8]);
	return 0;
}
点击查看代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll mod=2009;
struct Mat
{
	int n,m;
	int a[101][101];
	void zero()
	{
		memset(a,0,sizeof(a));
	}
	void one()
	{
		zero();
		for(int i=1;i<=n;i++)a[i][i]=1;
	}
	void resize(int x,int y)
	{
		n=x;m=y;
	}
	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]=(res.a[i][j]+(ll)a[i][k]*A.a[k][j])%mod;
				}
			}
		}
		return res;
	}
	void out()
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
				cout<<a[i][j]<<" ";		
			cout<<endl;
		}

	}
};
ll n;
Mat qpow(Mat A,ll b)
{
	Mat res;
	res.resize(9*n,9*n);
	res.one();
	while(b)
	{
		if(b&1)res=res*A;
		b>>=1;
		A=A*A;
	}
	return res;
}
int pos(int u,int v)
{
	return u+n*v;
}
int main()
{
	int T;
//	ios_base::sync_with_stdio(false);
//	cin.tie(0);cout.tie(0);
	cin>>n>>T;
	Mat res;
	int x;
	res.resize(9*n,9*n);
	res.zero();
	for (int i = 1; i <= n; ++i)
	{
		for (int j = 1; j <= 8; ++j)
			res.a[pos(i, j)][pos(i, j - 1)] = 1; 
		for (int j = 1; j <= n; ++j)
		{
			scanf("%1d", &x); 
			if (x)
 				res.a[i][pos(j, x - 1)] = 1; 
		}
	}
	res=qpow(res,T);
	cout<<res.a[1][n];
	return 0;
}

标签:ch,mat,int,ll,矩阵,read,小点,乘法
From: https://www.cnblogs.com/wlesq/p/18103426

相关文章

  • 【C#】while循环 输出四种形式的九九乘法表
    首先创建一个控制台应用程序(一)第一种阶梯inti=1;while(i<=9){intj=1;while(j<=i){Console.Write("{0}*{1}={2}\t",j,i,j*i);//\t的目的是让式子之间有一定间隔j++;}i++;Console.WriteLin......
  • 2017天梯赛总决赛:L1-8 矩阵A乘以B
    题目描述给定两个矩阵A和B,要求你计算它们的乘积矩阵AB。需要注意的是,只有规模匹配的矩阵才可以相乘。即若A有Ra​行、Ca​列,B有Rb​行、Cb​列,则只有Ca​与Rb​相等时,两个矩阵才能相乘。输入格式:输入先后给出两个矩阵A和B。对于每个矩阵,首先在一行中给出其行数R和列数C,随后R......
  • L1-080 乘法口诀数列
    注:考虑两个数字乘积是0的情况。#include<bits/stdc++.h>usingnamespacestd;intres[10000];intmain(){ inta,b,c; cin>>a>>b>>c; res[0]=a; res[1]=b; intpos=2; for(inti=0;;i++){ intans=res[i]*res[i+1]; vec......
  • Excel 如何批量将矩阵(多行多列)数据转为单行或单列数据
    该问题源于这样一个实践场景,试想有一个花名册,如下这样:现在需要根据这个花名册批量将其转换为考试时贴在桌上的小标签,如下这样:那么这个需求本质上就是将多行多列数据(考生姓名、考生编号、证件号码三列)转为单列数据(上图需求结果的第二列)。第一列是静态数据,第三列是递增数列,相对......
  • 304. 二维区域和检索 - 矩阵不可变(中)
    目录题目题解:二维前缀和题目给定一个二维矩阵matrix,以下类型的多个请求:计算其子矩形范围内元素的总和,该子矩阵的左上角为(row1,col1),右下角为(row2,col2)。实现NumMatrix类:NumMatrix(int[][]matrix)给定整数矩阵matrix进行初始化intsumRegion(introw1,......
  • Dijkstra邻接矩阵板子
    constintN=510;//节点个数intn;intg[N][N];//图intdist[N];//距离boolst[N];//判断点是否访问过intdijkstra(ints)//s表示起点,求s到任意点的最短距离{memset(dist,0x3f,sizeofdist);dist[s]=0;for(inti=0;i<n;i++){......
  • 代码随想录刷题记录4——滑动窗口和螺旋矩阵
    数组:701.二分查找27.移除元素977.有序数组的平方209.长度最小的子数组59.螺旋矩阵思路:209.长度最小的子数组只要知道要用滑动窗口的思路来写就好了!滑动窗口本质上就是双指针核心问题是考虑好窗口什么时候变大什么时候变小59.螺旋矩阵并没有什么新的算法思想,但......
  • 矩阵乘法学习笔记
    还是那句话,作者\(\LaTeX\)超级差。定义首先矩阵定义扔出来:域\(K\)上的一个\(n×m\)的矩阵可以看作一个\(n×m\)的数表。记为:\[A_{n×m}=\begin{bmatrix}A_{1,1}&\cdots&A_{1,m}\\\vdots&\ddots&\vdots\\A_{n,1}&\cdots&A_{n,m}\end{bmatrix}\]矩阵加法soeasy.......
  • 百度【灵境矩阵】智能体开发初学笔记
    AIAgent(人工智能代理)是一种能够感知环境、进行决策和执行动作的智能实体。AIAgent可以称为“智能体”,也可以理解为“智能业务助理”,指在大模型技术驱动下,让人们以自然语言为交互方式高自动化地执行和处理专业或繁复的工作任务,从而极大程度释放人员精力。灵境矩阵是百度推出的......
  • 高等代数笔记:可逆矩阵
    目录方阵行列式性质可逆矩阵定义伴随矩阵与可逆矩阵可逆矩阵的性质几个重要性质初等变换法方阵行列式性质可逆矩阵定义定义1对于数域K上的矩阵A,如果存在矩阵B,使得\(AB=BA=I\),那么称A是可逆矩阵(或非奇异矩阵).tips:1)A、B可交换=>可逆矩阵一定是方阵.2)如果A是可逆矩阵,那么B唯......