首页 > 代码库 > Shank的大步小步算法(Shank‘s Baby-Step-Giant-Step Algorithm)
Shank的大步小步算法(Shank‘s Baby-Step-Giant-Step Algorithm)
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <map> 5 typedef long long LL; 6 int mul_mod(int a,int b,int n){ // a、b都小于n 7 return a * b % n; 8 } 9 int pow_mod(int a,int p,int n){10 if(p == 0) return 1;11 LL ans = pow_mod(a,p / 2,n);12 ans = ans * ans % n;13 if(p % 2 == 1) ans = ans * a % n;14 return ans;15 }16 // 求x和y使得ax+by=d并且|x|+|y|最小。其中d=gcd(a,b)17 void exgcd(int a,int b,int& d,int& x,int& y){18 if(!b) d = a,x = 1,y = 0;19 else{20 exgcd(b,a % b,d,y,x);21 y -= x * (a / b);22 }23 }24 // 计算模n下a的逆,如果gcd(a,n) != 1,则逆不存在,返回-125 int inv(int a,int n){26 int d,x,y;27 exgcd(a,n,d,x,y);28 return d == 1 ? (x + n) % n : -1;29 }30 // 求解模方程a^x=b(mod n)。n为素数,无解时返回-1.31 int log_mod(int a,int b,int n){32 int m,v,e = 1,i;33 m = (int)sqrt(n + 0.5);34 v = inv(pow_mod(a,m,n),n); // a^m的逆v=a^(-m)35 std::map<int,int> x; // x[j]表示满足ei(=a^i)=j的最小的i36 x[1] = 0;37 for(int i = 1 ; i < m ; i++){ // 计算ei38 e = mul_mod(e,a,n);39 if(!x.count(e)) x[e] = i;40 }41 // 考虑a^(im)、a^(im+1)、...、a^(im+m-1)42 for(int i = 0 ; i < m ; i++){43 if(x.count(b)) return i * m + x[b];44 b = mul_mod(b,v,n);45 }46 return -1;47 }48 int main(){49 printf("%d\n",log_mod(3,4,5));50 return 0;51 }
Shank的大步小步算法(Shank‘s Baby-Step-Giant-Step Algorithm)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。