当前位置: 首页 > news >正文

大步小步算法扩展大步小步算法

创建时间:2025-05-29


大步小步算法

大步小步算法(Baby Step Giant Step,BSGS)运用了 Meet in the Middle 的思想,用根号的时间求出 \(a\)\(p\) 互质时方程 \(a^x \equiv b \pmod p\) 的最小非负整数解,过程如下:

由欧拉定理知:\(a^{\varphi(p)} \equiv 1 \pmod p\),所以 \(a^{\varphi(p)+x} \equiv a^x \pmod p\)\(a^{k\varphi(p)} \equiv a^v \pmod p(k \in \N)\),所以当 \(a^x \equiv b \pmod p\) 有解时,一定也存在一个 \(x \in [0, \varphi(p))\) 的解。

\(x=At-B(A,B\in \N^*,t \in N^*,B \le t)\),则 \(a^{At-B} \equiv a^x \equiv b \pmod p\),同乘 \(a^B\)\(a^{At} \equiv a^Bb \pmod p\)。我们可以先从小到大枚举 \(B\),计算出 \(a^Bb \bmod p\) 的值,并将每个值对应的最大的 \(B\) 存入哈希表(因为 \(x=At-B\),所以 \(B\) 越大 \(x\) 越小)。再从小到大枚举 \(A\),计算 \(a^{At}\) 的值,并试着在哈希表中找到一个 \(a^{At}\) 对应的 \(B\),若找到了则立即返回答案 \(At-B\)(当 \(A'>A\) 时,\(A't-B'\) 一定大于 \(At-B\))。因为 \(x<\varphi(p)<p\),所以只需从 \(1\) 枚举到 \(p\) 即可,若还没找到答案,则原方程无解。

这个算法的复杂度为 \(O(\frac p t+t)\),显然,当 \(t=\sqrt p\) 时复杂度最小,为 \(O(\sqrt p)\)。不过为了保险起见,通常取 \(t=\sqrt p + 1\)

PS:由于枚举 \(A\)\(a^{At}\) 每次扩大到原来的 \(a^t\) 倍,称之为“大步”;枚举 \(B\)\(a^Bt\) 每次扩大到原来的 \(a\) 倍,称之为“小步”。故该算法得名“大步小步”。

代码:

int qpow(int a, int k, int p) {int res = 1;while (k) {if (k & 1)res = res * a % p;a = a * a % p;k >>= 1;}return res;
}int BSGS(int a, int b, int p) {unordered_map<int, int> hs;int t = sqrt(p) + 1, bs = b * a % p;for (int B = 1; B <= t; B++) {hs[bs] = B;bs = bs * a % p;}int pw = qpow(a, t, p), gs = pw;for (int A = 1; A <= t; A++) {if (hs.count(gs))return A * t - hs[gs];gs = gs * pw % p;}return -1;
}

注:之所以要求 \(a \perp p\) 互质是因为在求出 \(a^{At} \equiv a^Bb \pmod p\) 后需要通过两边同时除以 \(a^B\) 才能得到 \(a^x(a^{At-B})\) 的解,而为了保证同余式仍然成立,必须有 \(a^B \perp p\),所以 \(a \perp p\)

扩展大步小步算法

扩展大步小步(Extend Baby Step Giant Step,exBSGS),将求解方位扩展到了 \(a\)\(p\) 不互质的情况,下面是它的求解过程:

将高次同余方程 \(a^x \equiv b \pmod p\) 变形为 \(a \cdot a^{x-1}+p \cdot y=b\),我们可以先用裴蜀定理判定它是否有解,即 \(\gcd(a,p) \mid b\) 是否成立,若不成立,即无解,直接返回 \(-1\) 即可。若成立,则令 \(d=\gcd(a,p)\),再将其变形为 \(\frac a d \cdot a^{x-1}+ \frac p d \cdot y=\frac b d\),这个方程又与同余方程 \(\frac a d \cdot a ^{x-1} \equiv \frac b d \pmod {\frac p d}\) 是等价的。显然 \(\frac a d\)\(\frac p d\) 是互质的,所以 \(\frac a d\) 存在模 \(\frac p d\) 意义下的逆元,所以可以将方程变为 \(a^{x-1} \equiv \frac b d (\frac a d)^{-1} \pmod {\frac p d}\),继续并向下递归求出该高次同于方程的解,直至 \(\gcd(a,p)=1\) 时,直接用大步小步算法求解并返回;若下层方程无解,则本层的方程也无解,返回 \(-1\);否则将解加 \(1\) 并返回即可。

由于每向下递归一层 \(p\) 都要除以 \(d\),而 \(d\) 至少是 \(2\),所以一共有 \(\log p\) 层,每层都要求解最大公约数和逆元,再加上最后一层的普通大步小步,总的复杂度为 \(O(\log^2 p+\sqrt p)\)

代码:

int qpow(int a, int k, int p) {int res = 1;while (k) {if (k & 1)res = res * a % p;a = a * a % p;k >>= 1;}return res;
}int exgcd(int a, int b, int& x, int& y) {if (b == 0) {x = 1, y = 0;return a;}int x0, y0, d = exgcd(b, a % b, x0, y0);x = y0, y = x0 - a / b * y0;return d;
}int BSGS(int a, int b, int p) {unordered_map<int, int> hs;int t = sqrt(p) + 1, bs = b * a % p;for (int B = 1; B <= t; B++) {hs[bs] = B;bs = bs * a % p;}int pw = qpow(a, t, p), gs = pw;for (int A = 1; A <= t; A++) {if (hs.count(gs))return A * t - hs[gs];gs = gs * pw % p;}return -1;
}int exBSGS(int a, int b, int p) {a %= p, b = (b % p + p) % p;if (b == 1 || b == 0 && p == 1)return 0;int x, y, d = exgcd(a, p, x, y);if (b % d)return -1;if (d == 1)return BSGS(a, b, p);b /= d, p /= d;exgcd(a / d, p, x, y);int tmp = exBSGS(a, b * x % p, p);return tmp == -1 ? -1 : tmp + 1;
}

大步小步算法&扩展大步小步算法的应用

大步小步算法可以较快的求出 \(a_x \equiv b \pmod p\) 的解,但部分特殊无解情况大步小步算法无法判定出来,故使用时需谨慎判断有没有特殊情况;扩展大步小步算法的约束条件很少,但代码较为复杂且大多数情况大步小步算法已经足够解决问题,所以扩展大步小步算法在 OI 赛场上比较冷门,题目也很少。

P3846 [TJOI2007] 可爱的质数/【模板】BSGS;
P4454 [CQOI2018] 破解D-H协议;
P4028 New Product;
P2485 [SDOI2011] 计算器;
P3306 [SDOI2013] 随机数生成器(数学归纳法+等比数列+大步小步算法);
P4884 多少个 1?(等比数列+大步小步算法);
P4195 【模板】扩展 BSGS/exBSGS(扩展大步小步算法模板)。

http://www.zskr.cn/news/1318637.html

相关文章:

  • HPM6750 LVGL性能优化:利用TCM与DMA突破嵌入式图形内存瓶颈
  • 新手入门指南使用 Python 快速调用 TaoToken 多模型服务
  • 手把手教你:如何给已有的海康威视监控系统(NVR/ivms-4200)加装新摄像头
  • Windows 11系统优化神器:Win11Debloat一站式去广告与性能提升指南
  • 终极指南:5步永久解锁Cursor Pro高级功能的完整解决方案
  • VisualCppRedist AIO:一站式Windows系统组件与运行时环境完整解决方案
  • 雨和虹防水维修:山东威海望海园富华城卫生间瓷砖空鼓翘边维修案例|真实业主实景施工,免砸砖根治反复松动发霉 - 雨和虹防水维修
  • 高硬度耐磨不锈钢厂商推荐:SUS630不锈钢厂商联系方式 - 品牌2025
  • ExifToolGUI完整指南:5分钟掌握照片元数据批量管理的终极技巧
  • 上海婚纱照什么风格好?新中式和日系怎么选 - eee888
  • 埃尔法 威尔法 皇冠 荣放改大灯 改LED升级激光透镜 北京哪里改 北京改灯TOP波波改灯 - 北京波波
  • 从用户搜索到智能排序:PinYin4j在Elasticsearch中文搜索优化中的实战应用
  • ORB-SLAM3跑KITTI实测:视觉惯性(VIO) vs 纯视觉,谁的轨迹更准?用evo评估告诉你
  • 从51到STM32:给单片机老手的STM32F103C8T6快速上手避坑指南
  • 焊接电路板一般温度多少
  • 实战指南:掌握applera1n工具的高效iOS iCloud绕过技巧
  • 从LED闪烁到任务调度:手把手教你用英飞凌AURIX的STM系统定时器构建简单时间片
  • 如何快速掌握QuPath:面向研究者的数字病理图像分析终极指南
  • Linux控制组资源统计生产排障流程
  • 保姆级教程:用Keil MDK V5.38从零搭建MM32F0130单片机工程(附完整文件结构)
  • 掌握Windows文件元数据管理工具,轻松解决文件混乱难题
  • Navicat无限试用终结者:Mac用户的3分钟重置指南
  • 如何永久保存微信聊天记录?WeChatMsg完整备份指南让数据永不丢失
  • 终极图片转3D模型解决方案:ImageToSTL完整指南与性能优化
  • Gemini Nano离线推理部署手册(移动端LLM轻量化部署终极版)
  • 给机器人调‘脾气’:手把手教你用松下A6-BE伺服调试串联机械臂(附避坑清单)
  • 从FCN到DeepLabv3+:一文读懂图像分割的10种主流深度学习模型(附代码实战)
  • 5分钟学会ExifToolGUI:照片元数据批量管理的终极解决方案
  • 别再死记硬背公式了!用Python脚本一键估算你的CPU/GPU真实算力(附代码)
  • R语言生存分析实战:从数据模拟到批量Cox回归,一键导出结果表格(附完整代码)