P7776 【模板】特征多项式 题解

21 篇文章 1 订阅

定理:相似矩阵特征多项式相同。

证明:|\rm PAP^{-1}-\lambda E|∣PAP−1−λE∣
=|\rm PAP^{-1}-\lambda PP^{-1}|=∣PAP−1−λPP−1∣
=|\rm (PA-\lambda P)P^{-1}|=∣(PA−λP)P−1∣
=|\rm P(A-P^{-1}\lambda P)P^{-1}|=∣P(A−P−1λP)P−1∣
=|\rm P(A-\lambda E)P^{-1}|=∣P(A−λE)P−1∣
=|\rm P|\times|A-\lambda E|\times |P^{-1}|=∣P∣×∣A−λE∣×∣P−1∣
=|A-\lambda E|=∣A−λE∣

考虑如何求出矩阵特征多项式。

朴素的消元方法由于涉及多项式运算,复杂度显然高于 O(n^3)O(n3)。

实对称阵可以相似对角化,但一般数域上的矩阵并不都能相似对角化,但可以消成如下类似对角矩阵的形式。

\begin{pmatrix} a_{1,1} & a_{1,2} & a_{1,3} & a_{1,4} & a_{1,5} \\ a_{2,1} & a_{2,2} & a_{2,3} & a_{2,4} & a_{2,5} \\ & a_{3,2} & a_{3,3} & a_{3,4} & a_{3,5} \\ & & a_{4,3} & a_{4,4} & a_{4,5} \\ & & & a_{5,4} & a_{5,5} \end{pmatrix} \quad⎝⎜⎜⎜⎜⎜⎛​a1,1​a2,1​​a1,2​a2,2​a3,2​​a1,3​a2,3​a3,3​a4,3​​a1,4​a2,4​a3,4​a4,4​a5,4​​a1,5​a2,5​a3,5​a4,5​a5,5​​⎠⎟⎟⎟⎟⎟⎞​

方法:构造初等矩阵 \rm PP 令 \rm A\leftarrow PAP^{-1}A←PAP−1 实现消元。

则用 a_{i+1,i}ai+1,i​ 消 a_{j,i}(j>i+1)aj,i​(j>i+1) 时,左乘和右乘分别相当于进行初等行变换 R_{j}\leftarrow R_j+kR_{i+1}Rj​←Rj​+kRi+1​ 和初等列变换 C_{i+1}\leftarrow C_{i+1}-kC_jCi+1​←Ci+1​−kCj​,由于 i<i+1<ji<i+1<j,可以注意到初等列变换不影响已消元部分,初等行变换仅影响当前要消的以及未消元部分。

化成如上矩阵后,可以轻易计算特征多项式。

考虑递推求解前 ii 行 ii 列的答案多项式 f_i(x)fi​(x)。显然边界是 f_0(x)=1f0​(x)=1。

观察矩阵可以发现,选取位于 a_{1,1},a_{2,2},\cdots,a_{j-1,j-1},a_{j,i},a_{j+1,j},a_{j+2,j+1},\cdots,a_{i,i-1}(1\le j\le i)a1,1​,a2,2​,⋯,aj−1,j−1​,aj,i​,aj+1,j​,aj+2,j+1​,⋯,ai,i−1​(1≤j≤i) 的元素是唯一有贡献部分,其贡献为 -f_{j-1}a_{j,i}\prod\limits_{k=j}^{i-1}a_{k+1,k}(j<i)−fj−1​aj,i​k=j∏i−1​ak+1,k​(j<i)。后面这部分显然可以直接递推。特别地,对于 j=ij=i,有额外贡献 xf_{i-1}xfi−1​。

于是我们可以 O(n^3)O(n3) 地计算出矩阵的特征多项式。

用途:写奇怪的 |\rm A-kE|∣A−kE∣ 多点求值板子。

据说可以加速矩阵快速幂,先咕着。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=502,p=998244353;
int a[N][N],f[N];
int n,i,j,k,x,y,r,q;
template<typename typC> void read(register typC &x)
{
	register int c=getchar(),fh=1;
	while ((c<48)||(c>57))
	{
		if (c=='-') {c=getchar();fh=-1;break;}
		c=getchar();
	}
	x=c^48;c=getchar();
	while ((c>=48)&&(c<=57))
	{
		x=x*10+(c^48);
		c=getchar();
	}
	x*=fh;
}
inline void inc(register int &x,const int y)
{
	if ((x+=y)>=p) x-=p;
}
inline void dec(register int &x,const int y)
{
	if ((x-=y)<0) x+=p;
}
inline int ksm(register int x,register int y)
{
	register int r=1;
	while (y)
	{
		if (y&1) r=(ll)r*x%p;
		x=(ll)x*x%p;y>>=1;
	}
	return r;
}
void calmatrix(int a[N][N],register int n)
{
	register int i,j,k,r;
	for (i=2;i<=n;i++)
	{
		for (j=i;j<=n&&!a[j][i-1];j++);
		if (j>n) {continue;}
		if (j>i)
		{
			swap(a[i],a[j]);//exit(-1);
			for (k=1;k<=n;k++) swap(a[k][j],a[k][i]);
		}
		r=a[i][i-1];
		for (j=1;j<=n;j++) a[j][i]=(ll)a[j][i]*r%p;
		r=ksm(r,p-2);
		for (j=i-1;j<=n;j++) a[i][j]=(ll)a[i][j]*r%p;
		for (j=i+1;j<=n;j++)
		{
			r=a[j][i-1];
			for (k=1;k<=n;k++) a[k][i]=(a[k][i]+(ll)a[k][j]*r)%p;
			r=p-r;
			for (k=i-1;k<=n;k++) a[j][k]=(a[j][k]+(ll)a[i][k]*r)%p;
		}
	}
}
void calpoly(int a[N][N],register int n,int *f)
{
	static int g[N][N];
	memset(g,0,sizeof(g));
	g[0][0]=1;
	register int i,j,k,r,rr;
	for (i=1;i<=n;i++)
	{
		r=p-1;
		for (j=i;j;j--)//第 j 行选第 n 列
		{
			rr=(ll)r*a[j][i]%p;
			for (k=0;k<j;k++) g[i][k]=(g[i][k]+(ll)rr*g[j-1][k])%p;
			r=(ll)r*a[j][j-1]%p;
		}
		for (k=1;k<=i;k++) inc(g[i][k],g[i-1][k-1]);
	}
	memcpy(f,g[n],n+1<<2);
//	if (n&1) for (i=0;i<=n;i++) if (f[i]) f[i]=p-f[i];//这题特殊(A-kE),否则注释掉
}
int main()
{
	read(n);//read(q);
	for (i=1;i<=n;i++) for (j=1;j<=n;j++) read(a[i][j]);
	calmatrix(a,n);calpoly(a,n,f);
	for (i=0;i<=n;i++) printf("%d%c",f[i]," \n"[i==n]);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值