模拟和逆元题目。
1. 题意
求
在 $[1,x]$ 的正整数解的个数,其中 $a,b,p,x$ 给定。
$p\leq10^6+3,x\leq10^{12},1\leq a,b<p$。
2. 思路
首先,看到 $p\leq10^6+3$,一定是要 $O(p)$ 枚举,然后再做。
a)枚举 $n$
那么,原题转化为了 $t\cdot a^n\equiv b\pmod p$ 的解了。
很明显是一个 BSGS,时间复杂度为 $O(\sqrt p)$ 或 $O(\sqrt p\log \sqrt p)$,取决于 map 还是 Hash。
但是,总时间为 $O(p\sqrt p)$,很明显无法通过。
b)枚举 $a^n$
首先,我们考虑 $a^n$ 的取值有多少种。
由于 $a^{p-1}\equiv 1\pmod p$,所以循环节一定是 $p-1$,那么我们就可以枚举 $n\bmod (p-1)$,得到所有的 $a^n$ 的取值。
那么,原题就是 $n\cdot t\equiv b\pmod p$ 的解。
咦,这不就是一个逆元了吗?
于是,我们可以 $O(\log p)$ 求出逆元(因为一定有),那么,我们就可以求出 $n\bmod p$ 的值。
c)合并答案
这道题在 CF 上有中国剩余定理的标签,大概就是这里用的吧。
我们已经得到了 $t1=n\bmod (p-1)$ 和 $t2=n\bmod p$ 的值,直接由中国剩余定理就可以了。
其实手玩也不是不可以,直接设 $n=kp+t2$,代入第一个就可以得到:
就解出了 $n$ 的最小正整数取值了。
周期很明显是 $p\cdot(p-1)$,将答案加入即可。
3. 代码
实际实现的时候可以预处理算出 $a$ 的逆元,每次枚举 ${a^t}$ 的逆元的时候可以通过 ${a^{t-1}}^{-1}$ 乘上 $a^{-1}$ 即可。
码风略丑,请见谅。
1 | int main() |