問題:固定模數 \(p\),多次回答某個數 \(a\) 的逆元。強制在線。
本文提供一個 \(O(p^{\frac{2}{3}})\) 預處理,\(O(1)\) 查詢的做法。
首先定義一下 Farey 序列:記 \(F_{m}\) 表示所有分母不超過 \(m\) 的最簡真分數構成的有序數列。例如 \(F_5 = \{\frac{0}{1}, \frac{1}{5}, \frac{1}{4}, \frac{1}{3}, \frac{2}{5}, \frac{1}{2}, \frac{3}{5}, \frac{2}{3}, \frac{3}{4}, \frac{4}{5}, \frac{1}{1}\}\)。可以認為 \(\frac{0}{1}, \frac{1}{1}\) 也是最簡真分數。
Farey 序列有一個性質:對於 \(F_m\) 中任意相鄰兩個分數 \(\frac{x}{y}, \frac{z}{w}\),一定滿足 \(yz - xw = 1\)。
事實上,\(F_m\) 可以由 \(F_{m - 1}\) 擴展得到。對於 \(F_{m - 1}\) 中任意相鄰兩個分數 \(\frac{x}{y}\) 和 \(\frac{z}{w}\),如果 \(y + w = m\),就在這兩個分數中間插一個 \(\frac{x + z}{y + w}\),這樣就得到了 \(F_m\)。驗算一下就能發現上述性質可以歸納證明。
我們只要運用下面的定理,就能解決原問題:
定理:對於任意整數 \(n \ge 2\) 和任意實數 \(v \in [0, 1]\),總是能在 \(F_{n - 1}\) 中找到 \(\frac{x}{y}\),滿足 \(|v - \frac{x}{y}| \le \frac{1}{yn}\)。更強地,這個 \(\frac{x}{y}\) 一定是 \(v\) 向前或向后找到的第一個分數。
考慮固定 \(n\),令 \(v = \frac{a}{p}\)。那么就有 \(|\frac{a}{p} - \frac{x}{y}| \le \frac{1}{yn}\)。
兩邊同乘 \(py\),得到 \(|ay - px| \le \lfloor \frac{p}{n} \rfloor\)。
這意味着 \(ay \equiv u \pmod p\),其中 \(|u| \le \lfloor \frac{p}{n} \rfloor\)。因為 \(a^{-1} = u^{-1}y\),所以只要預處理出所有不超過 \(\lfloor \frac{p}{n} \rfloor\) 的數的逆元即可。
這樣還有兩個問題:怎么不用排序生成 Farey 序列;怎么 \(O(1)\) 找到 \(\frac{x}{y}\)。
發現序列中所有 \(\lfloor \frac{xn^2}{y} \rfloor\) 互不相同。我們開一個長度為 \(n^2\) 的 01 序列,每一位表示是否存在 \(\lfloor \frac{xn^2}{y} \rfloor\) 等於該下標。這樣就可以桶排序;並且查詢等價於查一個位置前后的第一個 \(1\),這個只要算一下 01 序列的前綴和即可。
預處理的時間是 \(O(n^2 + \frac{p}{n})\)。令 \(n = p^{\frac{1}{3}}\),我們就得到了 \(O(p^{\frac{2}{3}})\) 預處理,\(O(1)\) 查詢的算法。