1. 程式人生 > 其它 >「科技」線上 O(1) 逆元

「科技」線上 O(1) 逆元

問題:固定模數 \(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)\) 查詢的演算法。

提交記錄