隐藏页面特效

[BSGS]

[模板] 大步小步算法——BSGS算法

这个算法叫做B(拔)S(山)G(盖)S(世),或B(北)S(上)G(广)S(深)。 就是这么个骚东西。

大步小步算法用于解决:已知A, B, C,求X使得
A^x = B (mod C)
成立。


 

先令 x = i*m-j,其中 m=ceil(sqrt(p)),ceil是向上取整。

这样原式就变为    ai*m-j = b (mod p),

移项就变成了      ai*m = b*a(mod p)

枚举j (范围0-m) ,将 b*aj  存入hash表。

枚举i (范围1-m) ,从hash表中寻找第一个满足ai*m = b*aj  (mod p)。

此时   x = i*m-j  就是所要求的。


 

那么为什么只计算到 m=ceil(sqrt(q))  就可以确定答案呢?

 

因为 x = i*m-j , 所以x 的最大值不会超过p

 

由费马小定理知: 当p为质数且 (a,p1 时 ap-1 ≡ (mod p)

 

所以 当 x = p-1 时 ap-1 ≡ 1 会重新开始循环 所以 x 最大不会超过 p-1

 

所以:如果枚举 x 的话枚举到 p 即可。

 

所以使 imj<=p , 即 m=⌈√p⌉ , i,j 最大值也为m。

还有 我不保证 我写的 不会 出错(逃

1 #include <cstdio> 2 #include <iostream> 3 #include <cmath> 4 #include <map> 5 #include <algorithm> 6 7 using namespace std; 8 9 map<long long,long long> kkk; 10 11 int a,b,p,res; 12 13 bool flag; 14 15 long long GCD(long long a,long long b) 16 { 17 return !b ? a : GCD(b,a % b); 18 } 19 20 long long quickpower(long long a,long long b,long long p) 21 { 22 long long ans = 1; 23 24 while(b) 25 { 26 if(b & 1) ans = ans * a % p; 27 28 a *= a; 29 b >>= 1; 30 } 31 32 return ans % p; 33 } 34 35 int main() 36 { 37 while(scanf("%d%d%d",&a,&p,&b) && a != 0 && b != 0 && p != 0) 38 { 39 flag = 0;// 判断的 40 41 if(a == b)// 特判 42 { 43 printf("1\n"); 44 45 flag = 1; 46 } 47 48 kkk.clear();//清空 49 50 if(GCD(a,p) != 1)// 不互质 51 { 52 printf("No Solution\n"); 53 54 continue; 55 } 56 57 int sq = ceil(sqrt(p));// 分块 58 59 int now = b % p;// j == 0; 60 61 kkk[now] = 0; 62 63 for(int j=1;j<=sq;j++) 64 { 65 now = now * a % p; 66 67 kkk[now] = j; 68 } 69 70 now = 1; 71 72 int power = quickpower(a,sq,p);//求 a^sq 73 74 for(int i=1;i<=sq;i++) 75 { 76 now = now * power % p;// 枚举 a^(i*sq) 77 78 if(kkk[now] && !flag)// flag 防止 多输出 , 如果找到了重复的 说明已经找到了 79 { 80 res = i * sq - kkk[now]; 81 82 printf("%d\n",(res + p) % p);// 保证不为负数 83 84 flag = 1; 85 86 } 87 } 88 89 if(!flag) 90 printf("No Solution\n"); 91 } 92 93 return 0; 94 }

 


__EOF__

本文作者风丨铃
本文链接https://www.cnblogs.com/-Wind-/p/10692634.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   风丨铃  阅读(296)  评论(2编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示