第一篇\(Blog\)...

还是决定把\(luogu\)上的那篇搬过来了。


BSGS,又名北上广深

它可以用来求\(a^x \equiv b (mod \ n)\)这个同余方程的一个解,其中\(a,n\)互质。

欧拉定理告诉我们,这里\(a^{\varphi(n)} \equiv 1 (mod \ n)\)

由于\(a^0 \equiv 1 (mod \ n)\),所以这里\(x\)到\(\varphi(n)\)后\(a^x \ mod \ n\)就开始循环了。

所以我们最坏情况就是\(n\)为素数时,从\(0\)到\(n-1\)枚举\(x\)就行了。

这样我们就得到了一个\(O(n)\)复杂度的优秀算法。

然而\(n < 2^{31}\)......

我们考虑让\(x = im - j(0 \le j \le m)\),即把\(0...n-1\)这\(n\)个数按每块大小为\(m\)分块。

就有

\[a^{im - j} \equiv b (mod \ n)
\]

两边同时乘\(a^j\)得

\[a^{im} \equiv ba^j (mod \ n)
\]

对于等式右边,总共只会有\(m+1\)种不同的\(j\),我们把\(ba^0,ba^1,...,ba^m\)全塞到一个\(map\)里,\(i\)也只会有\(\lceil \frac{n}{m} \rceil\)种取值,直接暴力。

最后复杂度为\(O(m + \lceil\frac{n}{m} \rceil)\)

取\(m = \lceil \sqrt{n} \rceil\),就可以做到\(O(\sqrt{n})\)

当然,用\(map\)的话还要乘上一个\(log\)。

其实分块的时候\(j\)取到\(m\)可能会导致有些\(x\)被考虑到两次,但并不影响,而且边界还不怎么需要处理。

贴一下Luogu P3846(板子题)的代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll; int fpow(int a, int b, int c){
int ret = 1;
for (a %= c; b; b>>=1, a = 1ll*a*a % c) if (b&1) ret = 1ll * ret * a % c;
return ret;
} int BSGS(int a, int b, int n, int &ret) {
int m = ceil(sqrt(n));
map<int,int> h;
for (int i = 0, tmp = b%n; i <= m; i++, tmp = 1ll*tmp*a%n)
h[tmp] = i;
a = fpow(a, m, n);
for (int tmp = a, i = 1; i <= m; i++, tmp = 1ll*tmp*a%n)
if (h.count(tmp)) { ret = 1ll*i*m - h[tmp]; return 1; }
return 0;
} int main(){
int a, b, n, flg, ans; scanf("%d%d%d", &n, &a, &b);
flg = BSGS(a, b, n, ans);
if (!flg) puts("no solution"); else printf("%d\n", ans);
return 0;
}

还有比较毒瘤的就是如果\(a \equiv 0 (mod \ n)\)的时候,需要特判\(b \not\equiv 0 (mod \ n)\)

因为如果\(a\)是\(n\)的倍数,那怎么乘都是\(0\)...

所以板子在这里:

int BSGS(int a, int b, int n, int &ret) {
a %= n, b %= n;
if (a == 0) { if (b == 0) { ret = 0; return 1; } else return 0; }
int m = ceil(sqrt(n)); map<int,int> h;
for (int tmp = b%n, i = 0; i <= m; i++, tmp = 1ll*tmp*a % n) h[tmp] = i;
a = fpow(a, m, n);
for (int tmp = a%n, i = 1; i <= m; i++, tmp = 1ll*tmp*a % n)
if (h.count(tmp)) { ret = 1ll*i*m - h[tmp]; return 1; }
return 0;
}

\(ExBSGS\)的话。。。改天学吧 感觉也没什么用

高次同余方程 $BSGS$的更多相关文章

  1. ACM_高次同余方程

    /*poj 3243 *解决高次同余方程的应用,已知 X^Y = K mod Z, 及X,Z,K的值,求 Y 的值 */ #include<cstdio> #include<cstr ...

  2. 数论之高次同余方程(Baby Step Giant Step + 拓展BSGS)

    什么叫高次同余方程?说白了就是解决这样一个问题: A^x=B(mod C),求最小的x值. baby step giant step算法 题目条件:C是素数(事实上,A与C互质就可以.为什么?在BSG ...

  3. HDU1452Happy 2004(高次幂取模+积性函数+逆元)

    题目意思:2004^x的所有正因数的和(S)对29求余:输出结果: 原题链接 题目解析:解析参照来源:点击打开链接 因子和 6的因子是1,2,3,6; 6的因子和是s(6)=1+2+3+6=12; 2 ...

  4. 【解高次同余方程】51nod1038 X^A Mod P

    1038 X^A Mod P 基准时间限制:1 秒 空间限制:131072 KB 分值: 320 X^A mod P = B,其中P为质数.给出P和A B,求< P的所有X. 例如:P = 11 ...

  5. 『高次同余方程 Baby Step Giant Step算法』

    高次同余方程 一般来说,高次同余方程分\(a^x \equiv b(mod\ p)\)和\(x^a \equiv b(mod\ p)\)两种,其中后者的难度较大,本片博客仅将介绍第一类方程的解决方法. ...

  6. 数论算法 剩余系相关 学习笔记 (基础回顾,(ex)CRT,(ex)lucas,(ex)BSGS,原根与指标入门,高次剩余,Miller_Rabin+Pollard_Rho)

    注:转载本文须标明出处. 原文链接https://www.cnblogs.com/zhouzhendong/p/Number-theory.html 数论算法 剩余系相关 学习笔记 (基础回顾,(ex ...

  7. 51Nod1039 N^3 Mod P 数论 原根 BSGS

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1039.html 题目传送门 - 51Nod1039 题意 题解 这题我用求高次剩余的做法,要卡常数. ...

  8. 51Nod1038 X^A Mod P 数论 原根 BSGS

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1038.html 题目传送门 - 51Nod1038 题意 题解 在模质数意义下,求高次剩余,模板题. ...

  9. CF1106F Lunar New Year and a Recursive Sequence 原根、矩阵快速幂、BSGS

    传送门 好久没写数论题了写一次调了1h 首先发现递推式是一个乘方的形式,线性递推和矩阵快速幂似乎都做不了,那么是否能够把乘方运算变成加法运算和乘法运算呢? 使用原根!学过\(NTT\)的都知道\(99 ...

随机推荐

  1. PCS 7 V9.0 SP1安装过程截图

  2. Beta阶段计划

    Beta阶段计划 JuJu   冲刺时间:12月27日至1月5号(遇到节假日顺延)   人员: 陈灿: 项目经理 金华:负责算法优化与提升 婷婷:同上 恩升:绘图 胡凯:对比pytorch的basel ...

  3. 动态代理,AOP和Spring

    笔记 1. 什么是AOP? Aspect-Oriented Programming 面向切面编程,关注一个统一的切面,相对于OOP(面向对象编程). 适合的场景: 日志 缓存 鉴权 如果用OOP来做怎 ...

  4. MySQL学习之SQL基础(一)DDL

    Sql基础 DDL (data defination language) 创建表 CREATE TABLE emp( ename varchar(10), hiredate date, sal dec ...

  5. POJ 3259:Wormholes bellman_ford判定负环

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 37906   Accepted: 13954 Descr ...

  6. day05-Python运维开发基础(双层循环、pass/break/continue、for循环)

    # ### 双层循环练习 # 十行十列小星星 j = 0 while j<10: # 逻辑代码写在下面 # 打印一行十个小星星 i = 0 while i<10: print(" ...

  7. 06.Delphi接口的不对等的多重继承

    uSayHello代码如下 unit uSayHello; interface uses SysUtils, Windows, Messages, Classes, Graphics, Control ...

  8. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-upload

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  9. require(): open_basedir restriction in effect. File(/www/wwwroot/xcx/zerg/thinkphp/start.php) is not within the allowed path(s): (/www/wwwroot/xcx/zerg/public/:/tmp/:/proc/) in /www/wwwroot/xcx/zerg/p

    解决方法: 在如下文件增加一项(如图所示) 在如下文件增加一项(如图所示): #php文件采用fastcgi解析并设置参数    location ~ \.php {        try_files ...

  10. 16.swoole学习笔记--异步事件

    <?php //异步事件 $fp=stream_socket_client(); fwrite($fp,"GET / HTTP/1.1\r\nHost:www.qq.com\r\n\r ...