先膜拜一波神仙yww

给定一个矩阵(没有任何特殊性质),如何求它的特征多项式?

算法一

直接把\(\lambda\)代入\((n+1)\)个点值,求完行列式之后插值即可。
时间复杂度\(O(n^4)\)

算法二

下面介绍一个更快的做法。
定义 对于矩阵\(\bm A,\bm B\), 若存在可逆矩阵\(\bm\Phi\)满足\(\bm A=\bm\Phi^{-1}\bm B\bm\Phi\), 则称\(\bm A\)和\(\bm B\)为相似矩阵,\(\bm\Phi\)称为桥接矩阵
定理 相似矩阵的特征多项式相同。
证明: 设\(\bm A\)和\(\bm B\)为相似矩阵,\(f(\lambda)\)和\(g(\lambda)\)分别为其特征多项式,则\(f(\lambda)=|\lambda \bm I-\bm A|=|\lambda \bm \Phi^{-1}\bm\Phi-\bm\Phi^{-1}\bm B\bm\Phi|=|\bm \Phi^{-1}(\lambda\bm I-\bm B)\bm\Phi|=|\bm\Phi^{-1}||\lambda \bm I-\bm B| |\bm\Phi|=|\bm\Phi^{-1}\bm\Phi|g(\lambda)=g(\lambda)\). 证毕。
于是我们可以考虑把没有特殊性质的矩阵化成有特殊性质的与之相似的矩阵来加速运算。
我们知道,对矩阵进行初等行(列)变换相当于将其左(右)乘一个可逆的初等矩阵,那么我们根据相似矩阵的定义,对\(\bm A\)进行初等行变换左乘初等矩阵的同时给它右乘同一初等矩阵的逆,不就构造出相似矩阵了吗?
简单推导可知,若左乘某一初等矩阵等价于把原矩阵第\(i\)行乘以\(x\)加到第\(j\)行上,则右乘该初等矩阵的逆矩阵等价于把原矩阵第\(j\)行乘以\(-x\)加到第\(i\)行上。

现在的问题是,我们对这个没有特殊性质的矩阵左乘初等矩阵的同时右乘它的逆,能把它变成什么有特殊性质的矩阵呢?
答案是,上海森堡矩阵。
定义 若一\(n\times n\)矩阵满足对于任意\(1\le j<j+1<i\le n\)的\((i,j)\), 矩阵第\(i\)行第\(j\)列值均为\(0\),则其为上海森堡矩阵
至于为什么是这个答案,首先变成上三角矩阵显然不现实,因为用第\(i\)行来消第\(j\)行 (\(j>i\))的第\(i\)列时对第\(i\)行和第\(j\)行进行了初等行变换,那这对应的初等列变换势必会影响第\(j\)列和第\(i\)列。那么我们可以考虑在消第\(i\)列的时候,用第\((i+1)\)行来消第\(j\)行 (\(j>i+1\))的第\(i\)列,这样进行的初等行变换是第\((i+1)\)行和第\(j\)行之间的,影响到的是第\((i+1)\)列和第\(j\)列,而不会影响第\(i\)列了。

现在问题转化为,如何快速求上海森堡矩阵的特征多项式?
这就非常简单了,最后一行只有两列有值,那么枚举选的是哪一列,如果选第\(n\)列,那么直接就是\((\lambda-a_{n,n})\)乘以左上角\((n-1)\times (n-1)\)的子矩阵的特征多项式;若选第\((n-1)\)列,那么第\((n-1)\)行选\((n-2)\)列,\((n-2)\)行选\((n-3)\)列……一直到某一行为止。假设这一行是第\((j+1)\)行选第\(j\)列 (\(0<j<n\)),那么第\(j\)行一定选第\(n\)列,前\((j-1)\)行选的就是前\((j-1)\)列了,而\(a_{n-1,n-2},a_{n-2,n-3},...,a_{j+1,j},a_{j,n}\)都是常数(都不在对角线上),所以直接递推即可。

时间复杂度\(O(n^3)\).

代码

(每一项对\(998244353\)取模, \(n\le 500\))

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<iostream>
#define llong long long
using namespace std;inline int read()
{int x=0; bool f=1; char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=0;for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');if(f) return x;return -x;
}const int N = 500;
const int P = 998244353;
llong a[N+3][N+3];
llong c[N+3][N+3];
int n;llong quickpow(llong x,llong y)
{llong cur = x,ret = 1ll;for(int i=0; y; i++){if(y&(1ll<<i)) {y-=(1ll<<i); ret = ret*cur%P;}cur = cur*cur%P;}return ret;
}
llong mulinv(llong x) {return quickpow(x,P-2);}void gauss()
{for(int i=1; i<=n; i++){if(a[i+1][i]==0){bool found = false;for(int j=i+2; j<=n; j++){if(a[j][i]!=0){for(int k=i; k<=n; k++) swap(a[i+1][k],a[j][k]);for(int k=1; k<=n; k++) swap(a[k][i+1],a[k][j]);found = false; break;}}if(found) {continue;}}for(int j=i+2; j<=n; j++){llong coe = P-a[j][i]*mulinv(a[i+1][i])%P;for(int k=i; k<=n; k++) a[j][k] = (a[j][k]+coe*a[i+1][k])%P;for(int k=1; k<=n; k++) a[k][i+1] = (a[k][i+1]-coe*a[k][j]%P+P)%P;}}
}void charpoly()
{c[0][0] = 1ll;for(int i=1; i<=n; i++){for(int j=0; j<=i; j++){c[i][j] = (c[i-1][j-1]-a[i][i]*c[i-1][j]%P+P)%P;}llong coe = P-1,cur = P-a[i][i-1];for(int j=i-2; j>=0; j--){llong tmp = cur*(P-a[j+1][i])%P;tmp = coe*tmp%P;for(int k=0; k<=j; k++){c[i][k] = (c[i][k]+c[j][k]*tmp)%P;}cur = cur*(P-a[j+1][j])%P;coe = P-coe;}for(int k=0; k<=i; k++) c[i][k] %= P;
//      printf("%d: ",i); for(int j=0; j<=i; j++) printf("%lld ",c[i][j]); puts("");}
}int main()
{scanf("%lld",&n);for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) scanf("%lld",&a[i][j]);gauss();
//  for(int i=1; i<=n; i++) {for(int j=1; j<=n; j++) printf("%lld ",a[i][j]); puts("");}charpoly();for(int i=0; i<=n; i++) printf("%lld ",c[n][i]); puts("");return 0;
}

【学习笔记】求矩阵的特征多项式相关推荐

  1. OpenGL超级宝典学习笔记——操作矩阵

    为了更强大的功能和灵活性,我们有时需要直接操作矩阵.在OpenGL中4x4的矩阵用包含16个浮点数值的一维数组来表示,而不是用二维的4x4的数组来表示.OpenGL之所以这么做,因为使用一维数组更高效 ...

  2. 学习笔记二.矩阵按键

    #学习笔记二:GPIO的探索与矩阵按键 ##1.在配置cubemx时,对gpio的配置有开漏输出和推挽输出两种方式, ###这里有一篇文章(别人的文章)讲的很详细link戳这里跳转 通俗来讲,推挽输出 ...

  3. MATLAB学习笔记(二) -- 矩阵和数组

    一.矩阵和数组的创建 函数法主要用于一些具有特许规律的矩阵. (1)zeros() -- 全零矩阵生成,ones() -- 全1矩阵 (2)eye() -- 单位矩阵,不支持二维以上的矩阵生成 (3) ...

  4. 【学习笔记】矩阵树定理(Matrix-Tree)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 一.矩阵树定理 二.常用定理 三.例题 1. Luogu P6178 [模板]Matrix-Tr ...

  5. OpenCV学习笔记:矩阵/向量处理

    环境:CentOS7 g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16) $ pkg-config --modversion opencv 2.4.13 总体上讲: ...

  6. 怎么用matlab建立一个魔方,Matlab学习笔记(2)矩阵与魔方

    一.输入矩阵 开始学习Matlab最好就是先知道如何输入矩阵 你可以依照以下几种方法进行输入矩阵: 1.直接输入矩阵的显式列表 2.从外部数据文件导入矩阵 3.利用方法来生成矩阵 4.利用M文件中自己 ...

  7. Python 学习笔记——求余数操作符 % 在数学计算中的应用-try_006_02

    今天做完这个习题后发现,原来学好编程可以用来解决一些数学上刁钻的难题,例如下题: 爱因斯坦的难题-- 爱因斯坦曾出过这样一道有趣的数学题:有一个长阶梯,若每步上2阶,最后剩1阶:若每步上3阶,最后剩2 ...

  8. C51单片机学习笔记之矩阵键盘

    简介 矩阵键盘一般为4×4或4×3的.矩阵键盘的判断方式分按行扫描和按列扫描. 简单说就是给全体一个高电平,然后给一个按键的一端附上低电平,再判断另一端是否为低电平. 原理图 代码部分 #includ ...

  9. 【numpy学习笔记】矩阵操作

    转置 a = np.array([[1,2,3],[3,4,5]],dtype='float') # array([[ 1., 2., 3.],[ 3., 4., 5.]]) a.T # array( ...

最新文章

  1. “Attention is All You Need 翻译
  2. Spring 5.0 源码编译, 403, 404 依赖pom 无法下载问题
  3. Google zerotouch方案介绍
  4. Linq 读取Xml 数据
  5. 解决Tomcat下源服务器未能找到目标资源的表示或者是不愿公开一个已经存在的资源表示
  6. java integer reverse_Leetcode7 Reverse Integer Java实现及分析
  7. 95-140-124-源码-transform-算子fold
  8. java正则表达式tab_Linux下如何使用grep命令查找带有tab(退格)的字符
  9. oracle 等待原因查找,查询引起锁等待的SQL语句
  10. 从零实现深度学习框架——手写前馈网络实现电影评论分类
  11. dlib android 识别时间,android dlib调用
  12. NDK开发基础④增量更新之客户端合并差分包
  13. Python电影推荐系统
  14. 六龙争霸3D国战怎么玩 国战玩法详解
  15. CentOS7部署YApi
  16. 大富翁源代码c语言,python版大富翁源代码分享.pdf
  17. iOS 5 故事板进阶(2)
  18. 我的专业我的梦作文计算机,我的创新我的梦优秀作文
  19. MySQL多表联表查询
  20. 由吃饭想到的产品痛点问题

热门文章

  1. cmd命令行下常见的注册表操作
  2. 文末有福利 | IT从业者应关注哪些技术热点?
  3. 哪个大学有计算机专业博士授权,哪些学校有计算机应用博士点
  4. Jetpack Compose - Icon
  5. nexus运行时异常org.apache.http.conn.ConnectTimeoutException
  6. Golang学习 - unicode 包
  7. 2021级-JAVA03 基础语法2--控制语句
  8. O034、 Nova Pause / Resume Instance 操作详解
  9. sqlsrver-常见英语单词释意
  10. springboot整合多线程ThreadPoolTaskExecutor