Ural 1013 K-based Numbers. Version 3 题解
题意
求 \(k\) 进制下,位数为 \(n\),没有两个相邻的 \(0\) 的数的个数。不能有前导零。答案对 \(m\) 取模。
\(2 \le n, k, m \le 10^{18}\)
初步思路
考虑数位 DP。
设 \(f(i, j)\) 表示已经考虑了前 \(i\) 位,\(j=0\) 时第 \(i\) 位是 \(0\),\(j=1\) 时第 \(i\) 位不是 \(0\),此时满足条件的数的个数。
初始化,\(f(1, 0) = 0\), \(f(1, 1) = k - 1\)。
答案是 \(f(n, 0) + f(n, 1)\)。
转移时,当 \(j=0\) 时上一位只能是 \([1, k)\),即 \(f(i, 0) = (k - 1) \times f(i - 1, 1)\);
当 \(j=1\) 时,上一位可以是 \(0\) 也可以是 \([1, k)\),即 \(f(i, 0) = f(i - 1, 0) + (k - 1) \times f(i - 1, 1)\)。
转移方程:
复杂度 \(O(n)\),肯定过不了。
优化
DP 本身复杂度基本没法优化了,那么我们从减少计算次数方面入手。
这时我们就可以用矩阵快速幂优化。
矩阵
快速幂
这个不用讲了吧。
但是快速幂是基于乘法的,那么矩阵的乘法是什么呢?
矩阵乘法
矩阵乘法只在第一个矩阵的列数和第二个矩阵的行数相同时才有意义。
设两个矩阵分别为 \(A\)(\(P\times M\) 的矩阵),\(B\)(\(M\times Q\) 的矩阵),设 \(C = A \times B\).
那么 \(C\) 是 \(P \times Q\) 的矩阵,且 \(C\) 第 \(i\) 行第 \(j\) 列的数为 \(A\) 第 \(i\) 行 \(M\) 个数与 \(B\) 第 \(j\) 列 \(M\) 个数分别相乘的和。
另外,矩阵乘法满足结合律,不满足一般的交换律。
矩阵快速幂
那么此时矩阵快速幂就是按照普通的快速幂求法来算。
应用矩阵优化
设 \(F(i)\) 表示 \(\begin{bmatrix}f(i, 0) &f(i, 1)\end{bmatrix}\),那么我们希望通过 \(F(i - 1) = \begin{bmatrix}f(i - 1, 0) &f(i - 1, 1)\end{bmatrix}\) 推出 \(F(i)\)。
考虑推导一个矩阵 \(g\),使得 \(\begin{bmatrix}f(i - 1, 0) &f(i - 1, 1)\end{bmatrix} \times g = \begin{bmatrix}f(i, 0) &f(i, 1)\end{bmatrix}\),
怎么推呢?因为 \(f(i, 0) = 0 \times f(i - 1, 0) + (k - 1) \times f(i - 1, 1)\),所以 \(g\) 的第一列应该是 \(\begin{bmatrix}0\\k - 1\end{bmatrix}\),类似的第二列是 \(\begin{bmatrix}1\\k - 1\end{bmatrix}\),所以 \(g = \begin{bmatrix}0 & 1\\k - 1 & k - 1\end{bmatrix}\)。
整理思路
初始状态是 \(F(1) = \begin{bmatrix}0 & k - 1\end{bmatrix}\),通过不断乘 \(\begin{bmatrix}0 & 1\\k - 1 & k - 1\end{bmatrix}\) 得到 \(F(n) = \begin{bmatrix}f(n, 0) & f(n, 1)\end{bmatrix}\),答案就是 \(f(n, 0) + f(n, 1)\)。