「科技」在线 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} floor)

这意味着 (ay equiv u pmod p),其中 (|u| le lfloor frac{p}{n} floor)。因为 (a^{-1} = u^{-1}y),所以只要预处理出所有不超过 (lfloor frac{p}{n} floor) 的数的逆元即可。

这样还有两个问题:怎么不用排序生成 Farey 序列;怎么 (O(1)) 找到 (frac{x}{y})

发现序列中所有 (lfloor frac{xn^2}{y} floor) 互不相同。我们开一个长度为 (n^2) 的 01 序列,每一位表示是否存在 (lfloor frac{xn^2}{y} floor) 等于该下标。这样就可以桶排序;并且查询等价于查一个位置前后的第一个 (1),这个只要算一下 01 序列的前缀和即可。

预处理的时间是 (O(n^2 + frac{p}{n}))。令 (n = p^{frac{1}{3}}),我们就得到了 (O(p^{frac{2}{3}})) 预处理,(O(1)) 查询的算法。

提交记录

原文地址:https://www.cnblogs.com/Alfalfa-w/p/15388765.html