bsgs算法

Baby Step Giant Step算法,简称BSGS算法,也称为大步小步算法.

解决对象

离散对数:当x≡Gk(modm)x≡Gk(modm)x\equiv G^k\pmod m时,logG(x)≡k(modϕ(m))logG(x)≡k(modϕ(m))log_G(x)\equiv k\pmod{\phi(m)}。此处的logG(x)logG(x)log_G(x)是xxx以整数G'>GGG为底,模ϕ(m)ϕ(m)\phi(m)的离散对数。
BSGS算法就是用来求解Ax≡B(modC)Ax≡B(modC)A^x\equiv B\pmod C。原始的BSGS算法只能解决CCC是质数的问题。

求解步骤

设m=C'>m=C−−√m=Cm=\sqrt C向下取整,x=i×m+jx=i×m+jx=i\times m+j,那么,Ax=(Am)i×Aj,0≤i<m,0≤j<mAx=(Am)i×Aj,0≤i<m,0≤j<mA^x=(A^m)^i\times A^j,0\leq i。然后可以枚举iii,这是一个O(C)'>O(C−−√)O(C)O(\sqrt C)级别的枚举。
对于枚举的每一个iii,都令D=(Am)i'>D=(Am)iD=(Am)iD=(A^m)^i,令E=AjE=AjE=A^j,那么就有D×E≡B(modC)D×E≡B(modC)D\times E\equiv B\pmod C。然后用扩展欧几里得求解。
不过还应该特判AAA是C'>CCC的倍数的情况,比较容易。
对于多次调用AjAjA^j的情况,不用每次都用快速幂,只需要扔进hash表就可以了。

基本代码(用map模拟hash)

这道题
采用map,代码量比hash少的多了!!
(hash我调了好几天没调出来,后来换成map就过了,肯定是hash写错了)

#include<bits/stdc++.h>
using namespace std;
inline long long read()
{long long num=0;char c=' ';bool flag=true;for(;c>'9'||c<'0';c=getchar())if(c=='-')flag=false;for(;c>='0'&&c<='9';num=num*10+c-48,c=getchar());return flag ? num : -num;
}
int A,B,C;
namespace ksm
{long long qpow(long long a,long long t,long long p){int base=a%p;long long ans=1;while(t){if(t&1)ans=(long long)ans%p*(base%p)%p;base=(long long)base%p*(base%p)%p;t>>=1;}return ans;}
}namespace BSGS
{map<long long,int>mp;int bsgs(int A,int B,int C){mp.clear();if(A%C==0)return -1;int p=false;int m=ceil(sqrt(C));long long ans;for(int i=0;i<=m;i++){if(!i){ans=B%C;mp[ans]=i;continue;}ans=ans*A%C;mp[ans]=i;}long long t=ksm::qpow(A,m,C);ans=1;for(int i=1;i<=m;i++){ans=(ans*t)%C;if(mp[ans]){int t=i*m-mp[ans];return (t%C+C)%C;p=true;break;}}if(!p)return -1;}
}int main()
{int t=read();int l=read();if(l==1){using namespace ksm;while(t--){int a=read();int c=read();int b=read();printf("%lld\n",qpow(a,c,b));}return 0;}if(l==2){using namespace ksm;while(t--){int y=read();int z=read();int p=read();int gcd=__gcd(y,p);if(z%gcd){printf("Orz, I cannot find x!\n");continue;}printf("%d\n",((z%p)*(long long)qpow(y,p-2,p))%p);}}if(l==3){using namespace BSGS;using namespace ksm;while(t--){A=read();B=read();C=read();long long ans=bsgs(A,B,C); if(ans==-1){printf("Orz, I cannot find x!\n");continue;}printf("%lld\n",ans);}}return 0;
}

鸣谢这位大佬map的启示!
我是传送门

SDOI2011 计算器

题目描述

你被要求设计一个计算器完成以下三项任务:
1、给定y、z、p,计算yzmodpyzmodpy^z mod p 的值;
2、给定y、z、p,计算满足xy≡zxy≡zxy ≡z(mod p)的最小非负整数x;
3、给定y、z、p,计算满足yx≡z(mod p)yx≡z(modp)y^x ≡z(mod\ p)的最小非负整数x。
为了拿到奖品,全力以赴吧!

输入输出格式

输入格式:

输入文件calc.in 包含多组数据。
第一行包含两个正整数T、L,分别表示数据组数和询问类型(对于一个测试点内的所有数
据,询问类型相同)。
以下T 行每行包含三个正整数y、z、p,描述一个询问。

输出格式:

输出文件calc.out 包括T 行.
对于每个询问,输出一行答案。
对于询问类型2 和3,如果不存在满足条件的,则输出“Orz, I cannot find x!”。

输入输出样例

输入样例#1:

3 1
2 1 3
2 2 3
2 3 3

输出样例#1:

2
1
2

输入样例#2:

3 2
2 1 3
2 2 3
2 3 3

输出样例#2:

2
1
0

输入样例#3:

4 3
2 1 3
2 2 3
2 3 3
2 4 3

输出样例#3:

0
1
Orz, I cannot find x!
0

数据规模和约定

题解

这里有三种问法,第一种问法就直接是带模的快速幂,没啥好说的。
第二种问法就是求线性方程解,那就用扩展欧几里得!
第三种问法就是本文考虑的BSGS算法,也就是一个板子题目吧。怎么写板子前面已经介绍过了。

code

就是纯板子吧,直接照搬上面的代码就行了。

扩展BSGS

传统的bsgs只能解决c是质数的问题,如果c是合数,那就需要使用扩展bsgs。因为不是质数,所以不能直接求逆元。
扩展BSGS大概有那么几几个步骤:
设d=gcd(A,C)d=gcd(A,C)d=gcd(A,C),那么A,B,CA,B,CA,B,C可以表示为A=a∗d,B=b∗dA=a∗d,B=b∗dA=a*d,B=b*d(如果B不是d的倍数且B!=1B!=1B!=1则显然无解),C=c∗dC=c∗dC=c*d。代入原式可得a×(a×d)x−1≡b(modc)a×(a×d)x−1≡b(modc)a\times (a\times d)^{x-1}\equiv b\pmod c,如果我们把D×aD×aD\times a,那么左边就只剩下(a×d)x−1了(a×d)x−1了(a\times d)^{x-1}了,不停地求d=gcd(A,C)d=gcd(A,C)d=gcd(A,C),然后将B和C分别除以d。D要乘A/d,num++,直到d=1为止。
最后方程就成为这种形式了:D×Ax−num≡B(modC)D×Ax−num≡B(modC)D\times A^{x-num}\equiv B\pmod C。那么令x=i×m+j+numx=i×m+j+numx=i\times m+j+num,那么原先的BSGS一样处理就可以了。但是需要注意的是,x

数论——Baby Step Giant Step大步小步算法相关推荐

  1. 与数论的厮守03:大步小步算法

    这是个名字很新奇的算法.它用来求方程axΞb(mod c)的最小非负整数解,其中ac互质. 先看欧拉定理:aΦ(c)Ξ1(mod c).所以x肯定在0~Φ(c)-1里面.所以我们可以考虑枚举x.但显然 ...

  2. NOI数学:大步小步(Baby Step Giant Step,BSGS)算法

    BSGS算法求 高次同余方程:1.可爱的质数 2.计算器 BSGS算法求 高次同余方程:1.可爱的质数 2.计算器_啦啦啦32421的博客-CSDN博客 大步小步算法(BSGS)及扩展 & b ...

  3. 【数学】Baby Step,Giant Step

    给定整数 a,b,pa,b,pa,b,p 且 a,pa,pa,p 互质,请求出高次同余方程 ax≡b(modp)a^x\equiv b\pmod pax≡b(modp) 的非负整数解. 首先, a0≡ ...

  4. 离散对数(Baby Step Giant Step)

    现在我来介绍一种算法叫做Baby Step Giant Step.它是用来解决如下方程最小正整数解的     其中 如果,那么我们可以先取模,即,所以在这里我们只讨论的情况. 普通Baby Step ...

  5. BZOJ 2242([SDOI2011]计算器-Baby Step Giant Step第1题)

    2242: [SDOI2011]计算器 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 744  Solved: 289 [Submit][Statu ...

  6. BSGS 大步小步算法

    BSGS 大步小步算法,也叫拔山盖世算法,实质也是就利用分块+预处理的方式,来高效的解决 Ax≡B(modC)A^x\equiv B (modC)Ax≡B(modC)​​ 求最小的x 的问题.求中 C ...

  7. Shank的大步小步算法(Shank‘s Baby-Step-Giant-Step Algorithm)

    1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <map> ...

  8. bsgs(Baby Steps Giant Steps)算法

    BSGS算法(Baby Steps Giant Steps算法,大步小步算法,北上广深算法,拔山盖世算法) 适用问题 对于式子: $$x^y=z(mod_p)$$ 已知x,z,p,p为质数: 求解一个 ...

  9. 文本分类step by step(二)

    (注:如有转载请标明作者:finallyliuyu, 和出处:博客园) <文本分类 step by step(一)> 在<文本分类step by step(一)>中,我们从处理 ...

  10. Asp Net Core 5 REST API 使用 RefreshToken 刷新 JWT - Step by Step(三)

    翻译自 Mohamad Lawand 2021年1月25日的文章 <Refresh JWT with Refresh Tokens in Asp Net Core 5 Rest API Step ...

最新文章

  1. 全文翻译(全文合集):TVM: An Automated End-to-End Optimizing Compiler for Deep Learning
  2. ABAP开发中常用的两个F4搜索帮助函数的区别
  3. mysql between and 包含边界吗_10分钟让你明白MySQL是如何利用索引的
  4. QuickContact分析及其弹出窗口实现
  5. Spring的声明式事务管理
  6. python 定义变量怎么定义_python变量定义和定义规范
  7. 【转载】linux-查询rpm包相关安装、卸载脚本
  8. JScript多语言语法加亮引擎改进(修正多行注释识别)
  9. SQL常用语句总结整理
  10. 对讲机写频软件通用版_数字对讲机常规调频方法
  11. MATLAB 快速傅里叶变换分析
  12. 十三、直接、寄存器间接寻址、寄存器相对寻址、基址变址寻址、相对基址变址寻址
  13. 输入法公司Kika完成2.2亿B+轮融资 猎豹移动领投
  14. gdb reading symbols xxxx 段错误
  15. H3C wifi 命令
  16. pycharm验证码
  17. 你应该了解的 MySQL 细节
  18. iPh oto的删除动画
  19. 网站建设需要注意哪些(网站建设流程)
  20. 自适应简约风格个人主页html源码

热门文章

  1. 简单的水果价格排序(价格不重复)
  2. 播布客教学视频_C学习笔记_8.2_统计1到100中9的个数(函数)
  3. wait和notify,sleep
  4. unity4和unity5区别
  5. 苹果手机如何深度清理_安卓手机必备清理软件APP,完全免费超级深度清理
  6. 中国风?古典系?AI中文绘图创作尝鲜!⛵
  7. 不换门可以改开门的方向吗_防盗门可以更改开门方向吗?
  8. MAC 录屏工具,录制视频制作GIF—— LICEcap
  9. php 视频添加水印,记php调用ffmpeg给视频加文字水印
  10. 数据库设计4-概念结构设计