BSGS及扩展BSGS总结(BSGS,map)
蒟蒻哪里有什么总结,只能点击%YL%
还有这位ZigZagK大佬的blog
\(\mbox{BSGS}\)
给定\(a,b\)和模数\(\mbox{YL}\),求\(a^x\equiv b(\bmod\mbox{YL})\)中\(x\)的最小非负整数解。保证\(\gcd(a,\mbox{YL})=1\)。
设\(k=\lceil\sqrt{\mbox{YL}}\rceil\),令\(x=ky-c\)(\(y\in[1,k],c\in[0,k)\),故分解唯一)
于是有\(a^{ky}\equiv ba^c(\bmod\mbox{YL})\)
两边的取值都只有\(k\)种,枚举右边丢进map,再枚举左边查找一下即可得到最小的解。
复杂度\(O(\sqrt{\mbox{YL}}\log\sqrt{\mbox{YL}})\)。注意特判掉一些特殊情况。
#include<bits/stdc++.h>
#define LL long long
#define RG register
#define R RG int
using namespace std;
map<int,int>c;
inline LL qpow(RG LL b,R k,RG LL YL){//快速幂
RG LL a=1;
for(;k;k>>=1,b=b*b%YL)
if(k&1)a=a*b%YL;
return a;
}
int main(){
R a,b,YL;
cin>>YL>>a>>b;
if((b%=YL)==1)return puts("0"),0;//特判×2
if((a%=YL)==0)return puts("no solution"),0;
R k=sqrt(YL)+1,y;
RG LL p,pw=qpow(a,k,YL);
for(p=b,y=0;y<k;++y,(p*=a)%=YL)//预处理
c[(int)p]=y;
for(p=pw,y=1;y<=k;++y,(p*=pw)%=YL)//查找
if(c.count((int)p))return(cout<<(LL)k*y-c[(int)p]<<endl),0;
return puts("no solution"),0;//找不到
}
扩展\(\mbox{BSGS}\)
模板题:洛谷P4195 Spoj3105 Mod
双倍经验:洛谷SP3105 MOD - Power Modulo Inverted
可以解决\(\gcd(a,\mbox{YL})\neq1\)的情况,核心思想是试探性地约去\(\gcd\)。
同余方程\(a^x\equiv b(\bmod\mbox{YL})\),可以提一个\(a\)出来改成不定方程\(a\cdot a^{x-1}+\mbox{YL}\cdot y=b\),等于说暂时把\(a^{x-1}\)看成了未知数。
设\(g=\gcd(a,\mbox{YL})\),学完exgcd之后我们就知道了如果\(g\nmid b\)则方程组无解。否则就可以约成\(\frac a g\cdot a^{x-1}+\frac{\mbox{YL}}g\cdot y=\frac b g\)
我们把约简后的方程看作一个新的不定方程\(a'\cdot a^{x-1}+\mbox{YL}'\cdot y=b'\),如果\(\gcd(a,\mbox{YL}')\)还是不为\(1\)的话,我们就再从幂里面拿出一个\(a\)和\(\mbox{YL}'\)约。如此循环。
终于在约了\(cnt\)次后,我们得到了一个\(\gcd=1\)的方程了,变回来就是\(a'\cdot a^{x-cnt}\equiv b'(\bmod\mbox{YL}')\)
接下来的解法已经属于常规\(\mbox{BSGS}\)了,不过因为一些细节上的区别还是再写一遍。
仍然设\(k=\lceil\sqrt{\mbox{YL}'}\rceil\),令\(x=ky-c\)(\(y\in[1,k],c\in[0,k)\))
于是有\(a'\cdot a^{ky}\equiv ba^{cnt}\cdot a^c(\bmod\mbox{YL}')\),其实只是恒等号两边多乘了点东西而已。
约分多出来的复杂度是\(O(\log^2\mbox{YL})\),因为最多被约\(\log\)次,它的阶小于根号就忽略掉了。又要注意一些特判。
#include<bits/stdc++.h>
#define LL long long
#define RG register
#define R RG int
using namespace std;
map<int,int>c;
inline LL qpow(RG LL b,R k,RG LL YL){
RG LL a=1;
for(;k;k>>=1,b=b*b%YL)
if(k&1)a=a*b%YL;
return a;
}
int gcd(R x,R y){
return y?gcd(y,x%y):x;
}
int main(){
R a,b;RG LL YL;
cin>>a>>YL>>b;
while(a||b||YL){
R x=-1,a1=1,cnt=0,g,k,y,p,pw;
a%=YL;
if((b%=YL)==1){x=0;goto L;}//这个特判上面提过
while((g=gcd(a,YL))!=1){
if(b%g)goto L;//无解充要条件
++cnt;b/=g;YL/=g;
a1=a/g*(LL)a1%YL;
if(a1==b){x=cnt;goto L;}
}//注意这个特判,此时等价于a^{x-cnt}≡1(mod YL)
c.clear();//多组数据注意清空
k=sqrt(YL)+1;//常规BSGS过程
pw=qpow(a,k,YL);
p=b*qpow(a,cnt,YL)%YL;
for(y=0;y<k;++y,p=(LL)p*a%YL)
c[p]=y;
p=(LL)a1*pw%YL;//多乘一个a1
for(y=1;y<=k;++y,p=(LL)p*pw%YL)
if(c.count(p)){x=k*y-c[p];break;}
L:~x?printf("%d\n",x):puts("No Solution");
cin>>a>>YL>>b;
}
return 0;
}
BSGS及扩展BSGS总结(BSGS,map)的更多相关文章
- BSGS与扩展BSGS
BSGS \(BSGS\)算法又称大步小步\((Baby-Step-Giant-Step)\)算法 \(BSGS\)算法主要用于解以下同余方程 \[A^x\equiv B(mod\ p)\]其中\(( ...
- BSGS和扩展BSGS
BSGS: 求合法的\(x\)使得\(a ^ x \quad mod \quad p = b\) 先暴力预处理出\(a^0,a^1,a^2.....a^{\sqrt{p}}\) 然后把这些都存在map ...
- BSGS及扩展BSGS算法及例题
\(BSGS(baby-step-giant-step)\)算法是用来解高次同余方程的最小非负整数解的算法,即形如这个的方程: \(a^x\equiv b(mod\ p)\) 其中\(p\)为质数(其 ...
- Codeforces 1106F Lunar New Year and a Recursive Sequence (数学、线性代数、线性递推、数论、BSGS、扩展欧几里得算法)
哎呀大水题..我写了一个多小时..好没救啊.. 数论板子X合一? 注意: 本文中变量名称区分大小写. 题意: 给一个\(n\)阶递推序列\(f_k=\prod^{n}_{i=1} f_{k-i}b_i ...
- BSGS 和扩展
BSGS BSGS,全称叫 BabyStepGiantStep,也就是大步小步 其实还是比较暴力的 它可以\(O(\sqrt p)\)的复杂度内解出: \[a^x\equiv n\pmod p,\gc ...
- BSGS及其扩展
目录 定义 原理 朴素算法 数论分块 例题 Luogu2485 [SDOI2011]计算器 题解 代码 扩展 例题 Luogu4195 [模板]exBSGS/Spoj3105 Mod 代码 之前写了一 ...
- python3-知识扩展扫盲易忘-map,collections.Counter()的用法
map() 会根据提供的函数对指定序列做映射. 第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表. >> ...
- 数论算法 剩余系相关 学习笔记 (基础回顾,(ex)CRT,(ex)lucas,(ex)BSGS,原根与指标入门,高次剩余,Miller_Rabin+Pollard_Rho)
注:转载本文须标明出处. 原文链接https://www.cnblogs.com/zhouzhendong/p/Number-theory.html 数论算法 剩余系相关 学习笔记 (基础回顾,(ex ...
- BSGS算法学习笔记
从这里开始 离散对数和BSGS算法 扩展BSGS算法 离散对数和BSGS算法 设$x$是最小的非负整数使得$a^{x}\equiv b\ \ \ \pmod{m}$,则$x$是$b$以$a$为底的离散 ...
随机推荐
- 用WSDL4J解析types标签中的内容
WSDL4J是一种用来解析WSDL文本的常用工具. 但网络上用WSDL4J来解析wsdl文档complexType标签中内容的问题一大堆也没有有效的解决方法.今天在我“遍历”wsdl4j的api文档和 ...
- 【转】shell之for、while、until循环
一.简介 Shell编程中循环命令用于特定条件下决定某些语句重复执行的控制方式,有三种常用的循环语句:for.while和until.while循环和for循环属于“当型循环”,而unti ...
- MYSQL mydumper & myloader
第三方逻辑备份工具myduper和myloader | xiaoyu的数据库小窝-技术交流http://www.dbaxiaoyu.com/archives/1643 myloader原理0 - ze ...
- 硬盘扩容9999T
win+r运行创建命令:subst H: d:\123说明:H指的是想要创建的盘符,d:\123是文件路径 删除命令subst H: d/说明 :H指的是已创建的盘符,/d指的是删除的意思 注意新盘符 ...
- [转帖]cmd批处理常用符号详解
cmd批处理常用符号详解 https://www.jb51.net/article/32866.htm 很多符号 还是不清楚的.. 批处理能够极大的提高 工作效率 需要加强深入学习. 1.@一般在 ...
- [转帖]震惊,用了这么多年的 CPU 利用率,其实是错的
震惊,用了这么多年的 CPU 利用率,其实是错的 2018年12月22日 08:43:09 Linuxer_ 阅读数:50 https://blog.csdn.net/juS3Ve/article/d ...
- oracle计算时间常用函数
--ddd:一年中的第几天 select to_char(sysdate,'ddd') from dual --d:一周中的第几天 星期天是第一天 所以要-1select to_char(sysdat ...
- SpringMVC+Spring+Mybatis+AngularJS 多规格保存示例代码
insert时拿到最新增加的id值 绑定参数 js 实体类 Service实现类 Controller
- MyCat数据库中间件 - 分库
MyCat MyCat用于解耦分布式数据库与java,比如分库分表以后,需要查询某条数据时,需要java根据需要查的数据先计算去哪个库查,然而有了Mycat就不用自己计算怎么存储,怎么查询了.MyCa ...
- Linux基础学习(11)--Shell编程
第十一章——Shell编程 一.基础正则表达式 1.正则表达式与通配符(*,?,[ ]): 2.基础正则表达式: 二.字符截取命令 1.cut字段提取命令: 空格分割时,不知道空格有多少个,无法分割行 ...