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

Posted ezoilzh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BSGS算法 (小步大步 Baby Step Gaint Step)相关的知识,希望对你有一定的参考价值。

当你要求满足:

$$ A^x equiv B (mod P) $$

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

设 $ m=sqrt{P} $ 向上取整

处理一下那个式子:

$$ A^{i imes m-j} equiv B (mod P) $$
$$ A^{i imes m} equiv B imes A^j (mod 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
",ans);
37         else printf("no solution
");
38     }
39 }

证明:

有这样一条式子:

技术分享图片

证明了这个就搞定了

处理一下这个式子:

 技术分享图片

手头上的条件:gcd(A,P)=1
欧拉定理:技术分享图片

证完了OvO

 





以上是关于BSGS算法 (小步大步 Baby Step Gaint Step)的主要内容,如果未能解决你的问题,请参考以下文章

恶补数论 Baby-Step-Giant-Step 大步小步求离散模对数

bsgs(Baby Steps Giant Steps)算法

BSGS算法(大步小步算法)

BSGS与ExBSGS:大步小步法

BSGS(Baby-Step-Giant-Step)算法及其应用

Baby_Step,Gaint_Step(分析具体解释+模板)