Baby Step Giant Step 及其扩展算法
对于求解 A^x ≡ B (mod C) (0 <= x < C)
这样的问题,可以使用 Baby Step Giant Step
及其扩展算法解决。
对于BSGS,AC大神在他的博客中有一篇很详细的介绍,相信大部分人都是看他的文章学会BSGS的。这里我再做出一点整理。
Baby Step Giant Step
原始的BSGS只能解决C为素数的情况。
设m = ceil(sqrt(C)), x = i * m + j
,那么A^x = (A^m)^i * A^j, (0 <= i < m, 0 <= j < m)
。然后可以枚举i
,O(sqrt(C))
级别的枚举。
对于一个枚举出来的i
,令D = (A^m)^i
现在问题转化为求D * A^j ≡ B (mod C)
。如果把A^j
当作一个整体,那么套上exgcd就可以解出来了(而且因为C是质数,A是C的倍数的情况容易特判,除此之外必有(D, C) = 1
,所以一定有解)
求出了A^j
,现在的问题就是我怎么知道j
是多少?AC大神给出了一个非常聪明的方法,先用O(sqrt(C))
的时间,将A^j
全部存进hash表里面。然后只要查表就在O(1)
的时间内知道j
是多少了。
Extended Baby Step Giant Step
扩展过的BSGS不要求C为素数。大致的做法和没扩展的一样,只是有些修改。
Read on →