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

离散对数 bsgs 与 exbsgs

离散对数 bsgs 与 exbsgs

\(\mathcal O(\sqrt {P})\) 的复杂度求解 \(a^x \equiv b(\bmod P)\) 。其中标准 \(\tt BSGS\) 算法不能计算 \(a\)\(MOD\) 互质的情况,而 exbsgs 则可以。

namespace BSGS {
LL a, b, p;
map<LL, LL> f;
inline LL gcd(LL a, LL b) { return b > 0 ? gcd(b, a % b) : a; }
inline LL ps(LL n, LL k, int p) {LL r = 1;for (; k; k >>= 1) {if (k & 1) r = r * n % p;n = n * n % p;}return r;
}
void exgcd(LL a, LL b, LL &x, LL &y) {if (!b) x = 1, y = 0;} else {exgcd(b, a % b, x, y);LL t = x;x = y;y = t - a / b * y;}
}
LL inv(LL a, LL b) {LL x, y;exgcd(a, b, x, y);return (x % b + b) % b;
}
LL bsgs(LL a, LL b, LL p) {f.clear();int m = ceil(sqrt(p));b %= p;for (int i = 1; i <= m; i++) {b = b * a % p;f[b] = i;}LL tmp = ps(a, m, p);b = 1;for (int i = 1; i <= m; i++) {b = b * tmp % p;if (f.count(b) > 0) return (i * m - f[b] + p) % p;}return -1;
}
LL exbsgs(LL a, LL b, LL p) {if (b == 1 || p == 1) return 0;LL g = gcd(a, p), k = 0, na = 1;while (g > 1) {if (b % g != 0) return -1;k++;b /= g;p /= g;na = na * (a / g) % p;if (na == b) return k;g = gcd(a, p);}LL f = bsgs(a, b * inv(na, p) % p, p);if (f == -1) return -1;return f + k;
}
} // namespace BSGSusing namespace BSGS;int main() {IOS;cin >> p >> a >> b;a %= p, b %= p;LL ans = exbsgs(a, b, p);if (ans == -1) cout << "no solution\n";else cout << ans << "\n";return 0;
}
http://www.hskmm.com/?act=detail&tid=38024

相关文章:

  • 常见数列
  • 20232314 2025-2026-1 《网络与系统攻防技术》实验三实验报告
  • 【LTDC】LTDC 简介
  • 分类器案例 - -一叶知秋
  • Markdown数学公式 - -一叶知秋
  • 最大流
  • 最小割树 Gomory-Hu Tree
  • 最小割
  • 差分约束
  • 图论常见结论及例题
  • 最长路(topsort+DP算法)
  • 二分图最大匹配
  • 最短路径树(SPT问题)
  • 欧拉路径/欧拉回路 Hierholzers
  • 无源汇点的最小割问题 Stoer–Wagner
  • CF2152G
  • 染色法判定二分图 (dfs算法)
  • 链式前向星建图与搜索
  • 一般图最大匹配
  • 平面图最短路(对偶图)
  • 多源汇最短路(APSP问题)
  • 最小生成树(MST问题)
  • 缩点(Tarjan 算法)
  • 常见概念
  • 单源最短路径(SSSP问题)
  • CNCF项目记录2025-10
  • 关于 vue项目 代理的坑;baseURL必须为空;代理才会生效
  • 点分治 / 树的重心
  • 最近公共祖先 LCA
  • QMPlayer2中的类,数据结构