BSGS
(BSGS)演算法又稱大步小步((Baby-Step-Giant-Step))演算法
(BSGS)演算法主要用於解以下同餘方程
[A^xequiv B(mod p)]其中((A,P)=1),即(A)與(P)互質
前置知識
根據尤拉定理(A^{ varphi(p)} equiv1(mod p)),所以(A^x(mod p))的迴圈節為(varphi(p)).也就是說如果上面的方程有解(x),那麼肯定有(x in [0,varphi(p)]),所以我們可以列舉一下(x)求解
推導
上面是暴力的做法,而(BSGS)就是利用分塊的思想將上面的演算法複雜度優化為(sqrt{varphi(p)})(雜湊表做法)或者(sqrt{varphi(p)} log;p)(map)做法
我們令(m=lceil sqrt{varphi(p)}
ceil),那麼任何一個(xin [0,varphi(p)])都可以被表示成(im-j(i in [1,m],jin [0,m]))的形式
則原式可表示為[A^{im-j} equiv B(mod p)]
[A^{im}equiv A^jB(mod p)]
實現
所以先將右邊(A^jB(j in[0,m]))預處理出來,存到(hash)表中。
然後列舉左邊的(i in[1,m])計算出(A^{im}),並在(hash)表中查詢。
列舉(i,j)的複雜度都是(sqrt{varphi(p)}),常數取決於(hash)表
有個細節的地方,一般我們都是要求(x)最小的,所以我們希望(j)更大,(i)更小。所以在往(hash)表中存的時候,保留更大的那個(j)。從小到大列舉(i),遇到可行答案直接輸出即可。