基础BSGS

用处是什么呢w

大步小步发(Baby-Step-Giant-Step,简称BSGS),可以用来高效求解形如\(A^x≡B(mod C)\)(C为素数)的同余方程。

常用于求解离散对数问题。形式化地说,该算法可以在\(O(\sqrt{n})\)用于求解。

接下来是算法过程

首先我们讨论的都是(A,C) = 1(由于C是素数,所以等价于A不是C倍数)的情况,如果(A,C) > 1(A是C倍数),很容易特判掉。

先引入一个结论:

如果(A,C) = 1,那么对于\(x \in N\),有\(A^{x mod \phi(C)} ≡ A^x (mod C)\)

如下证明过程:

因为(A,C) = 1,根据欧拉定理,可得\(A^{k * \phi(C)} ≡ 1 (mod C)\)

设\(k \in N\),根据同幂性,\(A^{k * \phi(C)} ≡ 1 (mod C)\)

设\(a \in N\) 且 \(a < \phi(C)\),所以\(A^x(mod C)\),得证。

所以如果\(0 \leq x < \phi(C)\)无解,之后肯定也无解,但是\(\phi(C)\)并一定是最小正周期。

其算法本质是根号分治,令\(m=[\sqrt{C}]\),我们假设x = i * m - j,其中\(0 \leq i,j \leq m\),则有\(A^{i*m - j} ≡ B\) ,稍加变换,可以得到\(A^{i*m}≡B*A^j\)

我们现在已知的是\(A,B\),所以我们可以先通过枚举j,算出\(B * A^j\),用hash/map存下来,然后再枚举i,计算出\(A^{i * m}\)寻找是否有与之相等的\(B * A^j\),从而我们可以得到所有的\(x\),\(x = i * m - j\)

因为i,j都小于等于m,所欲复杂度为$ Θ(\sqrt{C})$,用map多一个log

进阶BSGS

问题:求解\(x^a ≡ b\) \(mod\) \(p\) (p为质数)

这个问题可以通过转化变成上面基础BSGS中所说的样子

因为\(p\)是一个质数,所以\(p\)一定存在一个原根\(g\),因此在模\(p\)的意义下的任何数\(x\),有且只有一个数\(i\)满足\(x = g^i\)

方法一

令\(x = g^c\),\(g\)是\(p\)的原根(肯定存在这个g和c),问题转化为求解\((g^c)^a ≡ b\) \(mod\) \(p\) ,可以转化为

\((g^a)^c ≡ b (mod p)\)

这就转化为基础篇中我们所说的内个式子了,可以在\(O(\sqrt{p})\)解出\(c\),这样可以得到原方程的一个特解 \(x_0 ≡ g^c\) \(mod\) \(p\)

方法二

我们仍令\(x = g^c\),并且设\(b = g^t\),于是乎我们得到 \(g^{ac}≡ g^t\) \(mod\) \(p\)

方程两边同时取离散对数可以得到 \(ac ≡ t\) \(mod\) \(\phi(p)\)

这样我们可以通过BSGS求解\(g^t ≡ b\) \(mod\) \(p\)得到\(t\),于是这就转化成为一个线性同余方程问题,这样也可以解出\(c\),求出\(x\)的一个特解\(x_0 = g^c ≡ b\) \(mod\) \(p\)

如果要找到\(x\)的所有解而不是特解的话:

我们能求出一个特解\(x_0 ≡ g^c (mod\) \(n)\),我们知道\(g^{\phi(n)} ≡ 1 (mod\) \(n)\),于是可以得到下面这个式子,
\[
\forall t \in Z,x^k ≡ g^{c*k+t*\phi(n)} ≡ a (mod p)$
\]

于是得到所有解为
\[
\forall t \in Z ,k|t * \phi(n),x ≡ g^{c+\frac{t * \phi(n)}{k}} ≡ a (mod p)
\]

然后对于上面这个式子有\(\frac{k}{gcd(k,\phi(n))}|t\)。因此我们设\(t = \frac{k}{gcd(k,\phi(n))}*i\),可以得到

\[
\forall i \in Z,x ≡ g^{c + \frac{\phi(n)}{gcd(k,\phi(n))} * i} (mod p)
\]

这就是原问题的所有解

下面是EXBSGS

与BSGS相类似,这个算法也是解决\(a^x≡b(mod p)\)的问题,只不过C可以不是质数。

我们知道,在\(a\)与\(p\)互质的时候,在模\(p\)的意义下\(a\)存在逆元,我们就可以用BSGS来解决问题,那么在他们不互质的情况下,我们就要使他们变成互质的。

具体来说,我们设\(d_i = gcd(a,p)\),如果\(d_1\)不是b的因子,那么原方程无解,有解的情况下我们将方程两边同时处以\(d_1\),可以得到
\[
\frac{a}{d_1} * a^{x - 1}≡\frac{b}{d_1} mod \frac{p}{d_1}
\]
如果\(a\)和\(\frac{p}{d_1}\)仍然不互质的话设\(d_2 = gcd(a,\frac{p}{d_1})\)。如果\(d_2\)不是\(\frac{b}{d_1}\),则方程无解,有解的情况下将方程两边同时除以\(d_2\),得到
\[
\frac{a^2}{d_1d_2} * a^{x - 2} ≡ \frac{b}{d_1d_2} mod \frac{p}{d_1d_2}
\]
同理,我们不停地这样判断,直到\(a\)与\(\frac{p}{d_1d_2...d_k}\)互质为止。

设\(D = \prod_{i = 1}^{k} d_i\),于是方程就变成了下面这样:
\[
\frac{a^k}{D} * a^{x - k} ≡ \frac{b}{D} mod \frac{p}{D}
\]
因为\(a\)与\(\frac{p}{D}\)互质,于是可是推出\(\frac{a^k}{D}\)与\(\frac{p}{D}\)互质,这样的话\(\frac{a^k}{D}\)就有逆元了,于是把它移到方程的右边,这就变成了一个BSGS问题,于是求解\(x - k\)后再加上\(k\)就是原方程的解了。

值得注意的是,不排除解小于等于k的情况,所以咋消因子前应\(O(k)\)枚举,直接验证\(a^i≡b\) \(mod\) \(p\),这样就能避免这种情况。

BSGS && EXBSGS的更多相关文章

  1. BSGS&EXBSGS 大手拉小手,大步小步走

    大步小步走算法处理这样的问题: A^x = B (mod C) 求满足条件的最小的x(可能无解) 其中,A/B/C都可以是很大的数(long long以内) 先分类考虑一下: 当(A,C)==1 即A ...

  2. BSGS&ExBSGS

    BSGS&ExBSGS 求解形如 \[a^x\equiv b\pmod p\] 的高次同余方程 BSGS 假装\(gcd(a,p)=1\). 设\(m=\lceil\sqrt p \rceil ...

  3. [note]BSGS & exBSGS

    BSGS (感觉这东西还是要写一下) BSGS主要用于求解形如\(x^k=y\pmod p\)(注意这里p与x互质)这样的方程的最小正整数解的问题 设\(m=\lceil\sqrt p\rceil,k ...

  4. 算法笔记--BSGS && exBSGS 模板

    https://www.cnblogs.com/sdzwyq/p/9900650.html 模板: unordered_map<int, int> mp; LL q_pow(LL n, L ...

  5. BSGS+exBSGS POJ2417+POJ3243

    a^x=b(mod p)求x,利用分块的思想根号p的复杂度求答案,枚举同余式两端的变量,用hash的方法去找最小的答案(PS:hash看上去很像链式前向星就很有好感).然后如果p不是质数时,就利用同余 ...

  6. Noip前的大抱佛脚----数论

    目录 数论 知识点 Exgcd 逆元 gcd 欧拉函数\(\varphi(x)\) CRT&EXCRT BSGS&EXBSGS FFT/NTT/MTT/FWT 组合公式 斯特林数 卡塔 ...

  7. 各种友(e)善(xin)数论总集(未完待续),从入门到绝望

    目录 快速幂 扩展欧几里得 GCD 扩展欧几里得 同余系列 同余方程 同余方程组 一点想法 高次同余方程 BSGS exBSGS 线性筛素数 埃式筛 欧拉筛 欧拉函数 讲解 两道水题 法雷级数 可见点 ...

  8. REHの收藏列表

    搬运自本人的AcWing,所以那里的文章会挺多. 友链(同类文章) :bztMinamoto 世外明月 mlystdcall 新人手册:AcWing入门使用指南 前言 有看到好文欢迎推荐(毛遂自荐也可 ...

  9. ZROI 2019 暑期游记

    ZROI 游记 在自闭中度过了17天 挖了无数坑,填了一点坑 所以还是有好多坑啊zblzbl 挖坑总集: 时间分治 差分约束 Prufer序列 容斥 树上数据结构 例题C (和后面的例题) 点分 最大 ...

随机推荐

  1. EL表达式无法获取boolean类型变量值

    今天调试个程序, 有个名为isAdmin的boolean类型的变量在jsp页面获取到的值为空, 这根本就是没获取到或者变量不存在的状况啊,但是在Action中明明是赋值成false了. 上网查了一下有 ...

  2. wget安装nginx

    #下载: wget http://nginx.org/download/nginx-1.8.0.tar.gz #解压: tar -zxvf nginx-1.8.0.tar.gz #安装依赖插件 yum ...

  3. ASP.NET MVC入门到精通——MVC请求管道

    https://www.cnblogs.com/jiekzou/p/4896315.html 本系列目录:ASP.NET MVC4入门到精通系列目录汇总 ASP.NET MVC的请求管道和ASP.NE ...

  4. bzoj 1483

    Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input 第 ...

  5. CodeForces - 645 C.Enduring Exodus

    快乐二分 用前缀和随便搞一下 #include <cstdio> using namespace std; ; int p[N]; ; inline int msum(int a, int ...

  6. 关于按下ctrl+z后,之后的cin失效的问题

    下面这代码按下Ctrl+z结束while输入后,接下来的cin >> val2就无法输入了 #include <iostream> #include <vector> ...

  7. K3老单序时簿开发示例

    K3需要对老单进行二次开发,老单的二次开发比较麻烦,这里整理一下老单序时簿上添加按钮的二次开发示例. --以下SQL脚本--获取 MENU IDselect FID,FmenuID,FName fro ...

  8. Linux 查看是否安装 oracle

    查看是否用 oracle 的进程 ps -ef | grep ora 一般安装 oracle ,默认会有 oracle 的用户. id oracle

  9. java基础(十三)之接口

    接口 什么是接口? 生活中也有很多的接口,比如USB接口.定义了接口就是定义了调用对象的标准. 接口基本语法 1.使用interface定义:2.接口当中的方法都是抽象方法:因为抽象函数不能生成对象, ...

  10. python3练习100题——025

    原题链接:http://www.runoob.com/python/python-exercise-example25.html 题目:求1+2!+3!+...+20!的和. 我的代码: s =[] ...