组合数学中的线性代数方法

瞎写一通

参考资料:https://sites.google.com/view/jozsefbaloghmath/teaching/math584

1.矩阵乘法

问题1.1:判断一个图中是否有三角形

暴力做是\(O(n^3)\)

考虑该图的邻接矩阵\(A\),枚举图的每条边\((a,b)\),我们想要判断是否存在\(c\)使得存在边\((a,c),(c,b)\),也就是\(A_{a,c}=A_{c,b}=1\)

\(A^2_{a,b}=\sum_{c=1}^nA_{a,c}A_{c,b}\),所以当\(A^2_{a,b}>0\),存在\(c\)使得\(A_{a,c}=A_{c,b}=1\)。所以我们可以使用\(O(n^{2.373})\)的矩阵乘法求解\(A^2\)后判断。

问题1.2:判断\(01\)矩阵\(A,B\)的乘积是否等于\(C\)

本部分会介绍Freivalds算法

暴力判断(用快速矩阵乘法)是\(O(n^{2.373})\)的,然而我们可以随机化:

均匀随机一个\(01\)向量\(x\),判断\(ABx\)是否等于\(Cx\)

\(ABx=A(Bx)\),所以能在\(O(n^2)\)的事件内计算\(ABx,Cx\)并判断。显然这个做法不会在\(AB=C\)时出错。

\(AB\neq C\)\((AB-C)\)至少有一行(设其为\(r\))非全\(0\)。那么\(r\cdot x=0\)时出错。

由于\(r\)的每一个位置地位相等,所以我们可以假设\(r\)的所有\(1\)处于前\(1,...,k\)列。

\(r\cdot x=0\)\(x\)的前\(1,...,k\)个元素有偶数个为\(1\),错误概率为\(\dfrac{\sum_{0\leq 2i\leq k}\dbinom{k}{2i}}{2^k}\)

根据熟知等式\(\sum_{0\leq 2i\leq k}=2^{k-1}\),所以在这一行错误判断概率为\(\frac{1}{2}\)

随机\(l\)次错误率为\(\frac{1}{2^l}\)

问题1.3:递推问题

在一交换环\((+,\cdot)\)上,定义递推数列\(f_i=\sum_{k=1}^nf_{i-k}\cdot a_i\),给定初值\(f_1,...,f_k\),我们想要快速求\(f_n\)

构造\(x=[f_k,...,f_1]^T\),我们构造\(M\),使得\(M^lx=[f_{k+a},...,f_{1+a}]^T\)。考虑让\(M[f_{k+a},...,f_{1+a}]^T=[f_{k+a+1},...,f_{2+a}]^T\)

使\(M_{i+1,i}=1\)\(M_{1,i}=a_{k-i+1}\) (\(1\leq i<k\)), \(M\)的其他元素为\(0\)

这个做法的瓶颈在于矩阵乘法,考虑使用多项式取模优化。

\(h(x)=x^k-\sum_{k=1}^ka_ix^{k-i},x^n=f(x)h(x)+r(x)\)(对\(x^n\)使用多项式长除法),那么\(\sum_{i=0}^{k-1}r(x)[x^i]a_{k-i}=f_n\)

证明:考虑一个序列\(b\)以及一个函数\(F(b)=\sum_{i\geq 0}b_if_i\)

\(n\geq k\)时,根据\(f_n\)的定义,对于任意环的元素\(s\),将\(b_n\)减去\(s\),并且对于所有\(1\leq i\leq k\)\(b_{n-i}\)加上\(sc_i\)\(F(b)\)不会改变

所以如果我们想要找到\(f_n\)并且\(n\geq k\),我们可以先令\(b_n=1\),并且令\(b\)的所有其他元素为\(0\)

然后将\(b_{n-i},1\leq i\leq k\)加上\(b_n\),将\(b_n\)变成\(0\),将\(n\)减去\(1\)。重复以上过程直到\(n<k\)\(\sum_{i=1}^{k-1}b_ia_{k-i}=f_n\)

\(f(x)=\sum_{n\geq 1}x^nf_i\),那么每一步等于对\(f(x)\)\(h(x)\)做长除法,并且停止条件也是\(\deg(f(x))\leq \deg(h(x))\)

所以\(\sum_{i=0}^{k-1}r(x)[x^i]a_{k-i}=f_n\)

问题1.4:一些图论问题

设图有\(n\)个点。

首先是如果我们要查询两个节点\(a,b\)之间经过\(k\)条边的路径的条数,我们可以考虑图的邻接矩阵\(A\)\(A^k_{a,b}\)就是答案(归纳易证)。

这样子时间复杂度是\(O(n^3\log_2k)\)

如果有多次查询,我们可以预处理\(A^{2^i}\)。考虑一个向量\(x\),初始\(x_a=1\)\(x\)的其他元素为\(0\),那么\((A^{k}x)_b\)就是答案。

由于向量乘矩阵时间复杂度是\(O(n^2)\),我们可以拆位,设\(k\)拥有二进制位\(2^a_0,2^a_1,...2^{a_l}\),我们可以将\(x\)左乘\(A^{2^{a_0}},...,A^{2^{a_n}}\),一次询问就是\(O(n^2\log_2k)\)

现在如果我们要查询两个节点\(a,b\)之间经过\(k\)条边的最短路径,我们可以考虑使用\((\min,+)\)矩阵乘法:\(C=AB,C_{i,j}=\min_k(A_{i,k}+B_{k,j})\)

那么那么\((A^{k}x)_b\)就是答案。同理可以使用上面的预处理优化时间复杂度(注意\((\min,+)\)矩阵乘法目前人类没有发现\(O(n^{3-\epsilon}),\epsilon>0\)的做法)

对于上述算法的一个运用是LOJ539:

2.线性无关性

3.图的特征值

3.1 基本性质

3.2 强正则图

posted @ 2026-07-31 15:48  notebooknote  阅读(9)  评论(0)    收藏  举报