【笔记】线性代数:矩阵的特征值 / 题解 ZROI2589【[23ab-day2] 喜欢】
problem
你有 \(A\cdot B\) 个节点,编号为 \(0\sim AB−1\),\(x,y\) 之间有边当且仅当 \(x\not\equiv y\pmod A\land x\not\equiv y\pmod B\),求生成树数量对 \(998244353\) 取模的结果。\(1\leq A,B\leq 10^{18}\)。
solution
一上来就矩阵树定理,\(10\) 分到手。打表 \(A\leq 3\),\(50\) 分到手(但是没取模挂了嘤嘤嘤)。
我们考虑爆算这个行列式。以下令 \(n=AB\),矩阵下标从 \(0\) 开始。
part 1 矩阵的特征值
想象在高维空间里有一个列向量 \(\vec v\),有一个矩阵 \(M\),如果我们将 \(M\) 左乘 \(\vec v\),得到 \(M\vec v\),那么这是一个列向量,是原来的 \(\vec v\) 的旋转、伸缩的结果,是原来的 \(\vec v\) 的线性组合。如果这个 \(M\vec v\) 和原来的 \(\vec v\) 的方向是一样的,我们称 \(\vec v\) 是矩阵的特征向量,伸缩的比值是矩阵的特征值 \(\lambda\),写作 \(M\vec v=\lambda\vec v\)(这里 \(\lambda\) 是一个数)。
特征值具有以下性质:
-
对于 \(n\) 阶方阵 \(M\),特征值有 \(n\) 个,可以有重复。
-
\(\det(M)=\prod_{i=0}^{n-1}\lambda_i\)。
-
\(tr(M)=\sum_{i=0}^{n-1}\lambda_i\),其中 \(tr(M)=\sum_{i=0}^{n-1}M_{i,i}\) 是矩阵的 迹,即主对角线之和。
-
特征多项式:将 \(\lambda\) 视作未知数,则 \(\det(M-\lambda I)\) 是矩阵的特征多项式。就是说,\(I\) 是单位矩阵,\(M-\lambda I\) 就是 \(M\) 这个矩阵的主对角线全部减去未知数 \(\lambda\),然后展开行列式的那一大坨东西,得到了一个 \(n\) 次多项式。平时看到的 \(|M-\lambda I|\) 就是这个东西,以下都用 \(|M|\) 表示行列式。
-
使得方程 \(|M-\lambda I|=0\) 成立的 \(\lambda\),一共有 \(n\) 个,对应 \(n\) 个特征值,所以 \(|M-\lambda I|=\prod_{i=0}^{n-1}(\lambda_i-\lambda)\)。
有些教材把特征多项式定义成 \(\det(\lambda I-M)\) 以避开对特征多项式取值时正负号的讨论。以下不改了。
part 2 特征多项式的使用
根据矩阵树定理,我们要求 度数矩阵 减 邻接矩阵(记为 \(M\))划去一行一列后的行列式,这是答案。矩阵树定理告诉我们,划去哪一行哪一列都是行的,算出来答案相同(都是生成树个数),那么记 \(M_i\) 表示 \(M\) 划去 \(i\) 行 \(i\) 列的矩阵,则我们可以求 \(ans=\frac{1}{n}\sum_{i=0}^{n-1}|M_i|\)。
这个转换有重大作用,根据行列式定义,我们可以将特征多项式展开得到:
这里的 \(S\),枚举的是“所有 \(\sigma_i=i\) 的且乘起来的时候选了 \(\lambda\) 的 \(i\) 的集合”,所以它是对的。
\(n\) 阶矩阵的特征多项式的 \(k\) 次项系数等于原矩阵的所有 \(n-k\) 阶主子式的行列式之和(乘上 \((-1)^k\))。
对 \(|M-\lambda I|\) 提取一次项系数得
非常完美,恰好是我们要求的东西(的 \(n\) 倍)。考虑怎么求他,我们套用另一个定义:
后面将说明 \(\lambda_0=0\),所以所求即为剩下 \(n-1\) 个特征值的乘积。
part 3 原矩阵的特征值
注意到我们原来的矩阵(度数矩阵 减 邻接矩阵)\(M\) 是一个循环矩阵,这比较显然。那么它的特征值有哪些呢?
我们取 \(\omega\) 为 \(n\) 次单位根(的某一个幂,只要求 \(\omega^n=1\)),构造
注意到单位根这种东西自带一个循环移位,如果使 \(\vec v\) 点乘 \(f(\omega)\),其中
则 \(M\vec v=f(\omega)\vec v\),所以 \(n\) 个 \(\vec v\) 是 \(M\) 的特征向量,\(n\) 个 \(f(\omega)\) 是原矩阵的特征值。
另一些证明:https://www.cnblogs.com/ac-evil/p/14734728.html
part 4 计算特征值
我们现在要计算所有特征值,只要把 \(\omega\) 代入 \(f\) 就好了,正常情况下我们可以 FFT,但这题不正常。
刻画 \(f\) 非常的容易,就是普通容斥:前面是度数在常数项,后面是邻接矩阵。
我们要带入 \(\omega\),看上去像单位根反演,试一下:
- \(f(1)=0\) 显然,所以有一个特征值为 \(0\),好久之前说要算的东西变成 \(\sum_{i=0}^{n-1}\prod_{j\neq i}\lambda_j=\prod_{i=1}^{n-1}\lambda_i\)。以下不考虑。
- 考虑 \(\sum_{i=0}^{B-1}x^{iA}\) 这一项,如果 \(x=\omega^k\),这里 \(\omega\) 是真的 \(n\) 次单位根,那么:
- \(B|k\) 时,原式等于 \(w^{AB}\) 的不知道多少次方求和,即 \(B\)。
- 否则等比数列求和,\(\dfrac{1-\omega^{kAB}}{1-\omega^{kA}}=\dfrac{1-1^k}{?\neq 0}=0\)。
- 其他项完全一样,所以这个东西等于
- \(f(\omega^k)=[k\not\mid AB]AB-[k\not\mid A]A-[k\not\mid B]B+[k\not\mid \gcd(A,B)]\gcd(A,B),k\neq 0\)。
- \(f(1)=0\)。
故逐个枚举那些东西是否成立并计算答案即可。简单容斥了。
code
人生苦短,没用 python。
int main(){
scanf("%lld%lld",&_A,&_B);
A=_A,B=_B;
LL ans=1;
i128 D=gcd(_A,_B),L=A/D*B;
i128 deg=A*B+D-A-B;
debug("A=%lld,B=%lld,D=%lld,L=%lld,deg=%lld\n",(LL)A,(LL)B,(LL)D,(LL)L,(LL)deg);
//i!=0
//A|i,B|i,d|i=>L|i
red(ans*=qpow(deg-D+A+B,D+(-1)));//except ab
//A|i,B\|i,d|i=>A|i,L\|i
red(ans*=qpow(deg-D+A,B-D));
//A\|i,B|i,d|i
red(ans*=qpow(deg-D+B,A-D));
//A\|i,B\|i,d|i
red(ans*=qpow(deg-D,L-A-B+D));
//d\|i,A\|i,B\|i
red(ans*=qpow(deg,A*B-L));
printf("%lld\n",mod(ans*qpow(A*B,P-2)));
return 0;
}
如果有问题再继续改!
本文来自博客园,作者:caijianhong,转载请注明原文链接:https://www.cnblogs.com/caijianhong/p/solution-zroi2589.html