1. 程式人生 > >BSGS算法 (小步大步 Baby Step Gaint Step)

BSGS算法 (小步大步 Baby Step Gaint Step)

ref std col des bubuko order problem wid 離散

當你要求滿足:

$$ A^x \equiv B \ (\bmod \ P) $$

的最小非負整數 x (gcd(A,P)==1)就可以用到 BSGS 了

設 $ m=\sqrt{P} $ 向上取整

處理一下那個式子:

$$ A^{i \times m-j} \equiv B \ (\bmod \ P) $$
$$ A^{i \times m} \equiv B \times A^j \ (\bmod \ P) $$

枚舉 j(0到m),將 B*A^j 存入hash表裏面
枚舉 i(1到m),從hash表中找第一個滿足上面這條式子的 j
x=i*m-j 即為所求 (感性理解)

模板題: 【xsy 1754】 離散對數

Description

給定B,N,P,求最小的滿足B^L=N(mod P)的非負正數L。保證gcd(B,P)=1。

Input

多組數據,每行三個空格隔開的整數P,B,N。

Output

對於每組數據,輸出答案。如無解,則輸出"no solution"

CODE:

 1 #include<iostream>
 2 #include<cmath>
 3 #include<cstdio>
 4 #include<unordered_map>
 5 using namespace std;
6 7 int p,a,b; 8 9 int qpow(int x,int y){ 10 int ans=1; 11 while(y){ 12 if(y&1)ans=1LL*ans*x%p; 13 y>>=1,x=1LL*x*x%p; 14 } 15 return ans; 16 } 17 18 int BSGS(){ 19 unordered_map<int,int> mp; 20 int m=ceil(sqrt(p)),tmp; 21 tmp=b; 22 for
(int j=0;j<=m;j++) 23 mp[tmp]=j,tmp=1LL*tmp*a%p; 24 tmp=a=qpow(a,m); 25 for(int i=1;i<=m;i++){ 26 if(mp.count(tmp)) 27 return i*m-mp[tmp]; 28 tmp=1LL*tmp*a%p; 29 } 30 return -1; 31 } 32 33 int main(){ 34 while(~scanf("%d%d%d",&p,&a,&b)){ 35 int ans=BSGS(); 36 if(~ans)printf("%d\n",ans); 37 else printf("no solution\n"); 38 } 39 }

證明:

有這樣一條式子:

技術分享圖片

證明了這個就搞定了

處理一下這個式子:

技術分享圖片

手頭上的條件:gcd(A,P)=1
歐拉定理:技術分享圖片

證完了OvO

BSGS算法 (小步大步 Baby Step Gaint Step)