P2144 [FJOI2007] 轮状病毒
Problem
一个 \(n\) 轮状基由圆环上 \(n\) 个不同的基原子和圆心的一个核原子构成。\(2\) 个原子之间的边表示这 \(2\) 个原子之间的信息通道。
\(n\) 轮状病毒的产生规律是在 \(n\) 轮状基中删除若干边,使各原子之间有唯一一条信息通道。
给定 \(n\ (n\le100)\),编程计算有多少个不同的 \(n\) 轮状病毒。
Solution
一眼矩阵树定理,但是没有取模!这说明要写高精度。
注意到这个图非常有规律,因此不妨手玩一下行列式。
将核原子编号为 \(1\),其余原子编号 \(2 \sim n + 1\),可以直接写出 \(n \times n\) 拉普拉斯矩阵:
\[\left[
\begin{matrix}
n & -1 & -1 & -1 & -1 & -1 & \cdots & -1 & -1 & -1 \\
-1 & 3 & -1 & 0 & 0 & 0 & \cdots & 0 & 0 & -1 \\
-1 & -1 & 3 & -1 & 0 & 0 & \cdots & 0 & 0 & 0 \\
-1 & 0 & -1 & 3 & -1 & 0 & \cdots & 0 & 0 & 0 \\
-1 & 0 & 0 & -1 & 3 & -1 & \cdots & 0 & 0 & 0 \\
\vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\
-1 & 0 & 0 & 0 & 0 & 0 & \cdots & -1 & 3 & -1 \\
-1 & -1 & 0 & 0 & 0 & 0 & \cdots & 0 & -1 & 3 \\
\end{matrix}
\right]_{(n + 1) \times (n + 1)}
\]
核原子过于独特,因此求余子式肯定选择 \(M(L(G))_{1, 1}\):
\[ans_{n} =
\left|
\begin{matrix}
3 & -1 & 0 & 0 & 0 & \cdots & 0 & 0 & -1 \\
-1 & 3 & -1 & 0 & 0 & \cdots & 0 & 0 & 0 \\
0 & -1 & 3 & -1 & 0 & \cdots & 0 & 0 & 0 \\
0 & 0 & -1 & 3 & -1 & \cdots & 0 & 0 & 0 \\
\vdots & \vdots & \vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\
0 & 0 & 0 & 0 & 0 & \cdots & -1 & 3 & -1 \\
-1 & 0 & 0 & 0 & 0 & \cdots & 0 & -1 & 3 \\
\end{matrix}
\right|_{n \times n}
\]
想把两个角上的 \(-1\) 消掉,这里选择对第一行进行拉普拉斯展开,得到:
\[ans_{n} =
3\times \left|
\begin{matrix}
3 & -1 & 0 & 0 & \cdots & 0 & 0 & 0 \\
-1 & 3 & -1 & 0 & \cdots & 0 & 0 & 0 \\
0 & -1 & 3 & -1 & \cdots & 0 & 0 & 0 \\
\vdots & \vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\
0 & 0 & 0 & 0 & \cdots & -1 & 3 & -1 \\
0 & 0 & 0 & 0 & \cdots & 0 & -1 & 3 \\
\end{matrix}
\right|_{(n - 1)\times (n - 1)}
+ \\
\left|
\begin{matrix}
-1 & -1 & 0 & 0 & \cdots & 0 & 0 & 0 \\
0 & 3 & -1 & 0 & \cdots & 0 & 0 & 0 \\
0 & -1 & 3 & -1 & \cdots & 0 & 0 & 0 \\
\vdots & \vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\
0 & 0 & 0 & 0 & \cdots & -1 & 3 & -1 \\
-1 & 0 & 0 & 0 & \cdots & 0 & -1 & 3 \\
\end{matrix}
\right|_{(n - 1)\times (n - 1)}
+
(-1)^{n}\left|
\begin{matrix}
-1 & 3 & -1 & 0 & 0 & \cdots & 0 & 0 \\
0 & -1 & 3 & -1 & 0 & \cdots & 0 & 0 \\
0 & 0 & -1 & 3 & -1 & \cdots & 0 & 0 \\
\vdots & \vdots & \vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\
0 & 0 & 0 & 0 & 0 & \cdots & -1 & 3 \\
-1 & 0 & 0 & 0 & 0 & \cdots & 0 & -1 \\
\end{matrix}
\right|_{(n - 1)\times (n - 1)}
\]
注意第一个行列式的形式已经很优美了,并且后两项行列式貌似可以化成第一个行列式的形式,可以设 \(f_{n}\) 表示形如第一项的 \(n\) 阶行列式,然后将后两项行列式用 \(f\) 表示,之后再考虑算 \(f\) 的事情。
注意到后两个行列式均有列向量 \(\left[
\begin{matrix}
-1 \\
0 \\
0 \\
\vdots \\
0 \\
-1 \\
\end{matrix}
\right]\),因此对这一列进行拉普拉斯展开比较科学。
化开中间的行列式:
\[\begin{aligned}
\dots &=
-
\left|
\begin{matrix}
3 & -1 & 0 & \cdots & 0 & 0 & 0 \\
-1 & 3 & -1 & \cdots & 0 & 0 & 0 \\
\vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\
0 & 0 & 0 & \cdots & -1 & 3 & -1 \\
0 & 0 & 0 & \cdots & 0 & -1 & 3 \\
\end{matrix}
\right|_{(n - 2)\times (n - 2)}
+
(-1)^{n + 1}\left|
\begin{matrix}
-1 & 0 & 0 & \cdots & 0 & 0 & 0 \\
3 & -1 & 0 & \cdots & 0 & 0 & 0 \\
-1 & 3 & -1 & \cdots & 0 & 0 & 0 \\
\vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\
0 & 0 & 0 & \cdots & -1 & 3 & -1 \\
\end{matrix}
\right|_{(n - 2)\times (n - 2)} \\
&= -f_{n - 2} - 1 \\
\end{aligned}
\]
(这里曾经有一个憨憨对三角矩阵进行拉普拉斯展开:|)
化开第三项行列式:
\[\begin{aligned}
\dots &=
(-1)^{n}\left(
-
\left|
\begin{matrix}
-1 & 3 & -1 & 0 & \cdots & 0 & 0 \\
0 & -1 & 3 & -1 & \cdots & 0 & 0 \\
\vdots & \vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\
0 & 0 & 0 & 0 & \cdots & -1 & 3 \\
0 & 0 & 0 & 0 & \cdots & 0 & -1 \\
\end{matrix}
\right|_{(n - 2)\times (n - 2)}
+(-1)^{n + 1}
\left|
\begin{matrix}
3 & -1 & 0 & 0 & \cdots & 0 & 0 \\
-1 & 3 & -1 & 0 & \cdots & 0 & 0 \\
0 & -1 & 3 & -1 & \cdots & 0 & 0 \\
\vdots & \vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\
0 & 0 & 0 & 0 & \cdots & -1 & 3 \\
\end{matrix}
\right|_{(n - 2)\times (n - 2)} \right) \\
&= -1 - f_{n - 2}
\end{aligned}
\]
整理一下,有:
\[\begin{aligned}
ans_{n} = 3f_{n - 1} - 2f_{n - 2} - 2 \\
\end{aligned}
\]
下面类似地求 \(f_{n}\):
\[\begin{aligned}
f_{n} &= \left|
\begin{matrix}
3 & -1 & 0 & 0 & \cdots & 0 & 0 & 0 \\
-1 & 3 & -1 & 0 & \cdots & 0 & 0 & 0 \\
0 & -1 & 3 & -1 & \cdots & 0 & 0 & 0 \\
\vdots & \vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\
0 & 0 & 0 & 0 & \cdots & -1 & 3 & -1 \\
0 & 0 & 0 & 0 & \cdots & 0 & -1 & 3 \\
\end{matrix}
\right|_{n\times n} \\
&= 3\left|
\begin{matrix}
3 & -1 & 0 & \cdots & 0 & 0 & 0 \\
-1 & 3 & -1 & \cdots & 0 & 0 & 0 \\
\vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\
0 & 0 & 0 & \cdots & -1 & 3 & -1 \\
0 & 0 & 0 & \cdots & 0 & -1 & 3 \\
\end{matrix}
\right|_{(n - 1)\times (n - 1)}
+
\left|
\begin{matrix}
-1 & -1 & 0 & \cdots & 0 & 0 & 0 \\
0 & 3 & -1 & \cdots & 0 & 0 & 0 \\
\vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\
0 & 0 & 0 & \cdots & -1 & 3 & -1 \\
0 & 0 & 0 & \cdots & 0 & -1 & 3 \\
\end{matrix}
\right|_{(n - 1)\times (n - 1)} \\
&= 3f_{n - 1} -
\left|
\begin{matrix}
3 & -1 & \cdots & 0 & 0 & 0 \\
\vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\
0 & 0 & \cdots & -1 & 3 & -1 \\
0 & 0 & \cdots & 0 & -1 & 3 \\
\end{matrix}
\right|_{(n - 2)\times (n - 2)} \\
&= 3f_{n - 1} - f_{n - 2} \\
\end{aligned}
\]
于是 \(f\) 可以递推计算,可以手算出边界 \(f_{1} = 3\),\(f_{2} = \left|
\begin{matrix}
3 & -1 \\
-1 & 3 \\
\end{matrix}
\right| = 8\)。
剩下的就是高精度处理了。
特判 \(ans_{1} = 1\),\(ans_{2} = 5\)。