1. 程式人生 > 其它 >Ural 1013 K-based Numbers. Version 3 題解

Ural 1013 K-based Numbers. Version 3 題解

DP 的複雜度瓶頸真的就是線性嗎?

Warning:
所有更新在原文釋出,在原文食用體驗更佳!

題意

題目連結

\(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)\)
轉移方程:

\[f(i, j) = \begin{cases} (k - 1) \times f(i - 1, 1) &(j = 0)\\ f(i - 1, 0) + (k - 1) \times f(i - 1, 1) &(j = 1) \end{cases} \]

複雜度 \(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\) 個數分別相乘的和。

\[C_{i, j} = \sum_{k=1}^M A_{i, k}B_{k, j} \]

另外,矩陣乘法滿足結合律,不滿足一般的交換律。

矩陣快速冪

那麼此時矩陣快速冪就是按照普通的快速冪求法來算。

應用矩陣優化

\(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)\)