O(1) 逆元的 (理论意义上) 比较健康的做法
备份一下这个做法, 省得以后反复跟别人解释了.
正如分块给出的实际上是一个
准确的说, 我们求的不止是逆元, 而是
观察. 对于非零正整数
a, b < X , 存在整数可逆矩阵M\in \mathrm{GL}_2(\mathbb Z) 使得且矩阵的元素的绝对值 $\| M\|_\infty <X^{1/2}$.
证明. 鸽笼原理足够, 但其实有一个更加算法化的证明是分析 Euclid 算法的执行过程, 这里略去.
推论. 对于非零正整数
a, b < X 以及参数B\leq X , 存在整数可逆矩阵M\in \mathrm{GL}_2(\mathbb Z) , 满足
证明. 对于
那么对于
显然, 上述的推论可以很容易的转换成一个算法.
处理阶段. 选定
查询阶段. 利用上述推论的构造:
- 不断在
\max(a, b)\geq 3B 的时候将一个数从X 变成X \cdot 3B^{-1/2} 大小, 然后再做一次辗转相除把另一个数也变小. - 直到当
a,b < 3B 的时候, 直接查表得到答案.
时间是
点评. 这个做法和 half-gcd 的关系某种意义上就类似于分块维护 操作 - 查询 和线段树的关系. half-gcd 的重点在于发现 推论 的部分是可以分治计算下去的, 这可以得到 整数 / 有限域上多项式 的辗转相除法的