学习了BSGS再学扩展的……
· 算法简述
- 前置算法
- BSGS
- GCD
- 大致内容
解决关于 $x$ 的方程 $A^x\equiv B\pmod{P}$ ,但是与 BSGS 不同的是 $A$ 和 $P$ 不需要互质(似乎“扩展”就是去掉了互质的条件)
· 算法证明
- 根据原方程,我们把它写成 $CA^x+kP=B$ ($k$ 是整数,最开始 $C=1$);
- 因为 $A,P$ 不互质,令 $g=(A,P)$ ;
- 将 1. 中的方程两边同除 $g$ ,得 $\frac{AC}{g}A^{x-1}+k\frac Pg=\frac Bg$;
- 但是上式左边是整数,如果右边是 分数 就无解了;
- 再把 3. 的等式还原成同余方程式:$\frac {AC}gA^{x-1}\equiv \frac Bg\pmod{\frac Pg}$ ;
- 上式中的 $\frac {AC}g$ 看做一个系数 $C’$,令 $x’=x-1$ ,$B’=\frac Bg$,$P’=\frac Pg$ ,则上式变为 $C’A^{x’}\equiv B’\pmod {P’}$ ;
- 因为 $C’$ 与 $P’$ 必然互质,那么 $C’A^{x’}$ 与 $P’$ 是否互质决定于 $A$ 和 $P’$ ;
- 所以重复上述过程,直到 $A$ 与 $P’$ 互质为止;
- 计 8. 的重复次数为 $t$;
- 这时候就可以用 BSGS 完成了,解出来的值为 $x-t$ ;
· 算法实现
(估计看上面的证明一些reader会懵,把 C++ 的实现写一下)
- 前置函数
int BSGS(int A,int B,int P,int pro)
是改变后的BSGS求解 $pro*A^x\equiv B\pmod P$ ($A,P$ 互质)的解;int QPow(int A,int B,int mod)
是快速幂求解 $A^B\bmod P$;int GCD(int A,int B)
是最大公约数求解 $(A,B)$;
- 扩展BSGS函数 (exBSGS)
- 参数
int exBSGS(int A,int B,int P)
,定义同BSGS(A,B,P,pro)
,只是 $A,P$ 可以不互质; - 定义
int tot
表示 3. 循环的次数,int pro
表示 $C’A^{x-t}$ 前面的系数 $C’$; - 循环:
- 判断
GCD(A,P)==1
,是则退出循环; - 否则记
int g=GCD(A,P)
; - 如果
B%g!=0
,则无解; - 再
P/=g
,B/=g
,tot++
,pro*=A/g
;
- 判断
- 此时我们就要求解 $pro*A^{x-tot}\equiv B\pmod{P}$ ;
- 用 BSGS 得到 $x-tot$ 的值,则
x=BSGS(A,B,P,pro)+tot
;
· 源代码(##POJ-3243##)
1 | /*Lucky_Glass*/ |
The End
Thanks for reading!
Email: lucky_glass@foxmail.com ,欢迎提问~