\(\rm{0x01\quad Preface}\)

\(emmm\)严格来讲,不应该被算到一个模板里面。因为在我看来模板是人构造出来的,但是这个算法应该是一个解决问题的\(process\)…更像是在解一道数学题,如果\(BSGS\)是定理的话,\(exBSGS\)更像是一个不断转化的过程233(手动@lxa并且溜

\(\rm{0x02\quad Algorithm~Process}\)

今天才发现原来\(\rm{BSGS}\)有两种写法……并且觉得剩下的题解讲的都讲的不是很全的样子233。

其实本质上,当\(p\)不为素数时,我们无法进行朴素\(\rm{BSGS}\)的原因是我们的欧拉定理\(a^{\varphi(p)} \equiv b(\bmod p)\) 只能处理\((a,p)=1\)的情况。那么我们知道,朴素的\(\rm{BSGS}\)的关键在于,可以保证最小解是有界的——\(x\)一定在\([1,\varphi(p)]\)中。所以最后\(BSGS\)的复杂度才会是\(\Theta(\sqrt{\varphi(p)})\) 的——比如说比较常见的\(p\)是素数的情况下,时间复杂度为\(\Theta(p)\)。

那么也就是说,我们只需要进行一些操作,保证$(a,p)=1 \(即可\)^{[1]}$。

我们思考,对于同余式\(a^x\equiv b~(\bmod p)​\)而言,我们先假定\((a,p)>1 ​\)。而此时如果有\(((a,p), b)=1​\),那么说明此式只有可能在\(x=0,b=1 ​\)的时候有解——这个结论是平凡的。因为假设我们把它展开成\(a\cdot a^{x-1} +kp=b ​\)的形式,必须要有\((a,p) ~|~ b​\)的情况下,才能保证\(a^{x-1}​\)和\(k ​\)都是整数。

那么对于\((a,p)>1\)且$(a,p)|b $,我们令原式变成

\[a^{x-1}\cdot \frac{a}{(a,p)} \equiv \frac{b}{(a,p)} (\bmod \frac{p}{(a,p)})
\]

的样子,如果此时\((a^{x-1},\frac{p}{(a,p)})=1\) 的话,我们就直接解

\[a^{x-1}\equiv \frac{\frac{b}{(a,p)}} {\frac{a}{(a,p)} }(\bmod \frac{p}{(a,p)})
\]

这个方程即可。否则我们继续分解直至\((p',a)=1\)。

那么此时有个问题需要注意,就是如果们在解这个方程时,出现了

\[(a^{x-1}, \frac{p}{(a,p)})\nmid \frac{\frac{b}{(a,p)}} {\frac{a}{(a,p)} }
\]

的情况,那我们需要特判并return -1 ;另一种情况,如果我们出现了

\[a^{x-1}\equiv \frac{\frac{b}{(a,p)}} {\frac{a}{(a,p)} } \equiv1(\bmod \frac{p}{(a,p)})
\]

的情况,也需要特判并输出此\(k\)(此时同余式左边是\(a^{x-k}\),因为\(a^{x-k}\equiv1~(\bmod p)\)所以直接输出\(k\)),不过也有可能不需要,完全看你写的\(BSGS\)能不能判断\(x=0\)的情况……一般情况下不能。

此时由于\(\boldsymbol{p}\)不再是素数,所以不能用费马小定理,需要我们用\(exgcd\)的方法求逆元,包括但不限于\(\frac{b}{(a,p)}\)的逆元和\(a^{-im}\)。

以下是完整版代码:


#include <map>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <unordered_map> #define ll long long using namespace std ;
unordered_map<ll, int> H ;
int N, M, P, ans ; // N ^x = M (mod P) inline ll gcd(ll a, ll b){
if (!b) return a ;
return gcd(b, a % b) ;
}
inline ll expow(ll a, ll b, ll mod){
ll res = 1 ;
while (b) res = ((b & 1)?res * a % mod : res), a = a * a % mod, b >>= 1 ;
return res ;
}
inline ll exgcd(ll &x, ll &y, ll a, ll b){
if (!b){ x = 1, y = 0 ; return a ; }
ll t = exgcd(y, x, b, a % b) ; y -= x * (a / b) ; return t ;
}
inline ll BSGS(ll a, ll b, ll mod, ll qaq){
H.clear() ; ll Q, p = ceil(sqrt(mod)), x, y ;
exgcd(x, y, qaq, mod), b = (b * x % mod + mod) % mod,
Q = expow(a, p, mod), exgcd(x, y, Q, mod), Q = (x % mod + mod) % mod ;
for (ll i = 1, j = 0 ; j <= p ; ++ j, i = i * a % mod) if (!H.count(i)) H[i] = j ;
for (ll i = b, j = 0 ; j <= p ; ++ j, i = i * Q % mod) if (H[i]) return j * p + H[i] ; return -1 ;
}
inline ll exBSGS(){
ll qaq = 1 ;
ll k = 0, qwq = 1 ;
if (M == 1) return 0 ;
while ((qwq = gcd(N, P)) > 1){
if (M % qwq) return -1 ;
++ k, M /= qwq, P /= qwq, qaq = qaq * (N / qwq) % P ;
if (qaq == M) return k ;
}
return (qwq = BSGS(N, M, P, qaq)) == -1 ? -1 : qwq + k ;
}
int main(){
while(cin >> N){
scanf("%d%d", &P, &M); if (!N && !M && !P) return 0 ;
N %= P, M %= P, ans = exBSGS() ; if (ans < 0) puts("No Solution") ; else cout << ans << '\n' ;
}
}

\(\rm{0x03\quad Afterword}\)

今天才知道原来\(BSGS\)有两种写法qaq

\(zyf2000\)好像和我写的\(BSGS\)对“大步”和“小步”的定义不是很一样…于是最后还是自己\(\rm{yy}\)的233

\(\rm{Reference}\)

exBSGS·BSGS-Senior/扩展的BSGS的更多相关文章

  1. BZOJ_2242_[SDOI2011]计算器_快速幂+扩展GCD+BSGS

    BZOJ_2242_[SDOI2011]计算器_快速幂+扩展GCD+BSGS 题意: 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p, ...

  2. BSGS及扩展BSGS总结(BSGS,map)

    蒟蒻哪里有什么总结,只能点击%YL% 还有这位ZigZagK大佬的blog \(\mbox{BSGS}\) 模板题:洛谷P3846 [TJOI2007]可爱的质数 给定\(a,b\)和模数\(\mbo ...

  3. BSGS及其扩展

    目录 定义 原理 朴素算法 数论分块 例题 Luogu2485 [SDOI2011]计算器 题解 代码 扩展 例题 Luogu4195 [模板]exBSGS/Spoj3105 Mod 代码 之前写了一 ...

  4. BSGS与扩展BSGS

    BSGS \(BSGS\)算法又称大步小步\((Baby-Step-Giant-Step)\)算法 \(BSGS\)算法主要用于解以下同余方程 \[A^x\equiv B(mod\ p)\]其中\(( ...

  5. BSGS和扩展BSGS

    BSGS: 求合法的\(x\)使得\(a ^ x \quad mod \quad p = b\) 先暴力预处理出\(a^0,a^1,a^2.....a^{\sqrt{p}}\) 然后把这些都存在map ...

  6. BSGS 和扩展

    BSGS BSGS,全称叫 BabyStepGiantStep,也就是大步小步 其实还是比较暴力的 它可以\(O(\sqrt p)\)的复杂度内解出: \[a^x\equiv n\pmod p,\gc ...

  7. BZOJ 2242: [SDOI2011]计算器( 快速幂 + 扩展欧几里德 + BSGS )

    没什么好说的... --------------------------------------------------------------------- #include<cstdio&g ...

  8. BSGS及扩展BSGS算法及例题

    \(BSGS(baby-step-giant-step)\)算法是用来解高次同余方程的最小非负整数解的算法,即形如这个的方程: \(a^x\equiv b(mod\ p)\) 其中\(p\)为质数(其 ...

  9. Codeforces 1106F Lunar New Year and a Recursive Sequence (数学、线性代数、线性递推、数论、BSGS、扩展欧几里得算法)

    哎呀大水题..我写了一个多小时..好没救啊.. 数论板子X合一? 注意: 本文中变量名称区分大小写. 题意: 给一个\(n\)阶递推序列\(f_k=\prod^{n}_{i=1} f_{k-i}b_i ...

随机推荐

  1. 小程序webview应用实践

    原文:小程序webview实践 作者:张所勇(转转开放业务部前端负责人) 公众号:大转转FE Fundebug经授权转载,版权归原作者所有. 大家好,我是转转开放业务部前端负责人张所勇,今天主要来跟大 ...

  2. lfs(systemd版本)学习笔记-第3页

    我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! lfs(systemd)学习笔记-第2页 的地址:https://www.cnblogs.com/renren-study-no ...

  3. jQ效果:jQuery和css自定义video播放控件

    下面介绍一下通过jquery和css自定义video播放控件. Html5 Video是现在html5最流行的功能之一,得到了大多数最新版本的浏览器支持.包括IE9,也是如此.不同的浏览器提供了不同的 ...

  4. FHQ Treap小结(神级数据结构!)

    首先说一下, 这个东西可以搞一切bst,treap,splay所能搞的东西 pre 今天心血来潮, 想搞一搞平衡树, 先百度了一下平衡树,发现正宗的平衡树写法应该是在二叉查找树的基础上加什么左左左右右 ...

  5. loadrunner 场景设计-添加Windows Resources计数器

    场景设计-添加Windows Resources计数器 by:授客 QQ:1033553122 目的 监控要测试的windows服务器的资源使用情况 步骤 1.添加视图,方法双击.拖动左侧的Windo ...

  6. 慕学在线网0.3_四个model

    1.四个model完整代码: # users/models.py from datetime import datetime from django.db import models from dja ...

  7. Apache POI导出excel表格

    项目中我们经常用到导出功能,将数据导出以便于审查和统计等.本文主要使用Apache POI实现导出数据. POI中文文档 简介 ApachePOI是Apache软件基金会的开放源码函式库,POI提供A ...

  8. 转:更改SQLServer实例默认字符集

    需求 安装数据库时,将字符集安装成了“SQL_Latin1_General_CP1_CI_AS”,现在需要将其更改为“Chinese_PRC_CI_AS”.   方法 重新生成系统数据库 ,然后还原配 ...

  9. ssh登陆慢的问题

    识别主机名时卡一下,关掉DNS选项: root@ns-virtual-machine:~# grep -i dns /etc/ssh/sshd_config UseDNS no 如果还有问题,打开ve ...

  10. Linux-lvm逻辑卷管理和提示丢失pv物理卷

    问题描述: 有次在使用lvm扩容的时候,整错了,导致显示如下情况 提示缺少一个pv导致无法继续,pvdisplay的时候查看到unknown 使用pvs查看找到pvname的unknown对应群组ce ...