「科技」在线 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)\) 查询的算法。

提交记录

posted @ 2021-10-10 10:28  alfalfa_w  阅读(3615)  评论(2编辑  收藏  举报