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

    提交记录

  • 相关阅读:
    Effective C++第三遍
    SQL基础教程
    hibernate 数据关联多对多
    hibernate 数据关联一对一
    hibernate 数据关联一对多
    hibernate Criteria查询
    hibernate HQL查询
    hibernate 持久化对象的生命周期
    hibernate的配置
    微博登录
  • 原文地址:https://www.cnblogs.com/Alfalfa-w/p/15388765.html
Copyright © 2020-2023  润新知