拔山盖世 北上广深
参考资料
前言
来到ZR之后的第二天,神仙dyh老师就讲了这个名字玄学的指数同余方程求解算法.
虽然在之前做某SDOI三合一模板-计算器的时候接触了一下这个算法,但是了解的并不深入,经过杜老师讲解之后,赶紧把它记下来.
BSGS
BSGS算法,全称为Baby-step Gaint-step算法,是一种求解指数同余方程的算法.
BSGS求解的指数同余方程是长这个样子:
$$a^x \equiv b(\mod p)$$
其中p是一个质数(实际上这里只要满足$\gcd(a,p) = 1$即可).
我们考虑设$x = qt + r$,$(t = \lceil \sqrt{p} \rceil)$那么原式变为:
$$a^{qt + r} \equiv b(\mod p)$$
然后我们移一下项:
$$a^{qt} \equiv b \cdot a^r(\mod p)$$
然后我们就要开始暴力啦!
暴力枚举$r$,把同余式右边的$ba^r$的所有值存到一个哈希表或者map里,然后再暴力枚举$q$,计算出$a^{qt}$次方所对应的值,然后从哈希表里查找这个值是否存在,如果存在,那么这就是一个原方程的解.
代码
1 | inline long long BSGS(long long a,long long b,long long p){ |
exBSGS
如果当$\gcd(a,p) \not = 1$时,普通的BSGS就过不去了.
因为我们BSGS出来的可能不是原方程的解,于是我们就需要进行扩展.
首先,显然当$\gcd(a,p) \not | b and b \not = 1$时,原方程无正整数解。
我们把这个同余式两边同时除一个$\gcd(a,p)$:
$$a^{x-1} \times \frac {a}{\gcd(a,p)} \equiv \frac {b}{\gcd(a,p)} (\mod \frac {p}{\gcd(a,p)})$$
然后我们设$g = (\frac {a}{\gcd(a,p)})^{-1} (\mod p)$
所以:
$$a^{x-1} \equiv \frac {bg}{\gcd(a,p)} (\mod \frac {p}{\gcd(a,p)})$$
然后我们令$x_0 = x-1,b_0 = \frac {bg}{\gcd(a,p)} q_0 = \frac {p}{\gcd(a,p)}$
于是我们不断递归这个过程,直到出现$\gcd(a,p) = 1$的情况之后BSGS即可.
代码
我们以LuoguP4195为例
1 | // luogu-judger-enable-o2 |