浅谈BSGS(大步小步)及其扩展
用途:
一般用来求\(a^x\equiv b\,\,(mod\,p)\)的最小正整数解,其中gcd(a,p)=1
设\(u=\lceil sqrt(p)\rceil\),则式子可以转化为\(a^{iu-j}\equiv b\,\,(mod\,p)\),其中\(i\in[1,u],j\in[0,u)\)
于是\(a^{iu}\equiv a^jb\,\,(mod\,p)\),我们就可以枚举j,存到map中,再枚举i判重就行了
不过当存在不同的j使\(a^jb\,mod\,p\)相同时,我们记录较大的(因为j越大答案越小嘛)
简易原理:
费马小定理:若gcd(x,p)=1,则有\(\\x^{p-1}\equiv1\,\,(mod\,p)\),得到\(x^p\equiv x\,\,(mod\,p)\)
所以当指数不小于p时,mod p的值会形成循环
Code:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
map<int,int> mp;
int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int quickpow(int a,int b,int p){
int re=1;
while(b){if(b&1) re=1ll*re*a%p;a=1ll*a*a%p;b>>=1;}
return re;
}
void solve(){
int p=read(),a=read(),b=read();
if(a%p==0){puts("Couldn't Produce!");return ;}
if(b==1){puts("0");return ;}
int u=sqrt(p)+1,v=b;mp.clear();
for(int i=0;i<u;i++)
mp[v]=i,v=1ll*v*a%p;
int w=quickpow(a,u,p);v=1;
for(int i=1;i<=u;i++){v=1ll*v*w%p;
if(mp.count(v)){
printf("%d\n",i*u-mp[v]);
return ;
}
}puts("Couldn't Produce!");
}
int main(){
int T=read();
while(T--) solve();
return 0;
}
扩展:
可以看到BSGS是有着局限性的,即必须满足gcd(a,p)=1
那么当gcd(a,p)!=1时呢?我们设\(d=gcd(a,p)\)
Step1:
我们首先判断\(b\)是否满足\(d|b\),若不满足,由裴蜀定理可知无解
Step2:
式子转化为:
\]
令\(c=\frac{a^k}{\Pi_{i=1}^kd_i},b'=\frac{b}{\Pi_{i=1}^kd_i},p‘=\frac{p}{\Pi_{i=1}^kd_i}\),若\(c=b'\),则直接输出\(k\)
Step3:
令\(d=gcd(a,p')\),若\(d\ne 1\),则返回step1,不过b变成了b'
全部完成后,我们得到式子:\(a^{x-k}c\equiv b'\,\,(mod\,\,p')\),此时满足\(gcd(a,p')=1\)
那么我们便可以直接BSGS了
Code:
#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long
using namespace std;
unordered_map<int,int> mp;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
inline int gcd(int x,int y){
if(y>x) swap(x,y);
while(y){swap(x,y);y=y%x;}
return x;
}
inline int quickpow(int a,int b,int p){
int re=1;
while(b){if(b&1) re=1ll*re*a%p;a=1ll*a*a%p;b>>=1;}
return re;
}
inline void solve(int a,int p,int b){
if(p==1){puts("0");return ;}
if(b==1){puts("0");return ;}
int d=gcd(a,p),flag=0,k=0,c=1;
while(d^1){
if(b%d){
puts("No Solution");
flag=1;break;
}p/=d,b/=d,++k;
c=1ll*c*(a/d)%p;
if(b==c){
printf("%d\n",k);
flag=1;break;
}d=gcd(a,p);
}if(flag) return ;
mp.clear();
int u=sqrt(p)+1,v=b;
for(int i=0;i<u;i++)
mp[v]=i,v=1ll*v*a%p;
v=c,c=quickpow(a,u,p);
for(int i=1;i<=u;i++){
v=1ll*v*c%p;
if(mp.count(v)){
printf("%d\n",i*u-mp[v]+k);
return ;
}
}puts("No Solution");
}
int main(){
while(1){
int a=read(),p=read(),b=read();
if(a==0&&b==0&&p==0) return 0;
a%=p;b%=p;solve(a,p,b);
}
}
话说为什么unordered_map比map快这么多啊,不过有时候编译会出锅...
浅谈BSGS(大步小步)及其扩展的更多相关文章
- 浅谈BSGS
用于求解形如\(a^x≡b\mod p\)的最小非负整数解\(x\). 由欧拉定理\(a^{\phi(p)}≡1\mod p\)可以知道,我们找的解如果有解则一定在\(\phi(p)\)范围内,而最大 ...
- 浅谈BSGS和EXBSGS
我的 BSGS 和各位犇犇的差不多,但是不需要求逆元 Luogu [ TJOI2007 ] 可爱的质数 原题展现 题目描述 给定一个质数 \(p\),以及一个整数 \(b\),一个整数 \(n\),现 ...
- [BSGS]大步小步算法
问题 BSGS被用于求解离散对数,即同余方程: \[ A^x\equiv B\pmod{P} \] 求\(x\)的最小非负整数解. 保证\(A\perp P\)(互质). 分析 首先,我们根据费马小定 ...
- 浅谈集合框架六——集合扩展:Arrays工具类、集合与数组相互转换方式;
最近刚学完集合框架,想把自己的一些学习笔记与想法整理一下,所以本篇博客或许会有一些内容写的不严谨或者不正确,还请大神指出.初学者对于本篇博客只建议作为参考,欢迎留言共同学习. 之前有介绍集合框架的体系 ...
- 浅谈集合框架四——集合扩展:集合循环输出方式及list输出方式的效率对比
最近刚学完集合框架,想把自己的一些学习笔记与想法整理一下,所以本篇博客或许会有一些内容写的不严谨或者不正确,还请大神指出.初学者对于本篇博客只建议作为参考,欢迎留言共同学习. 之前有介绍集合框架的体系 ...
- 离散对数&&大步小步算法及扩展
bsgs algorithm ax≡b(mod n) 大步小步算法,这个算法有一定的局限性,只有当gcd(a,m)=1时才可以用 原理 此处讨论n为素数的时候. ax≡b(mod n)(n为素数) 由 ...
- 【ASP.NET MVC系列】浅谈ASP.NET MVC八大类扩展(上篇)
lASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操 ...
- BSGS&EXBSGS 大手拉小手,大步小步走
大步小步走算法处理这样的问题: A^x = B (mod C) 求满足条件的最小的x(可能无解) 其中,A/B/C都可以是很大的数(long long以内) 先分类考虑一下: 当(A,C)==1 即A ...
- [模板]大步小步算法——BSGS算法
大步小步算法用于解决:已知A, B, C,求X使得 A^x = B (mod C) 成立. 我们令x = im - j | m = ceil(sqrt(C)), i = [1, m], j = [0, ...
随机推荐
- Revo Uninstaller Pro - 真正彻底卸载软件不留垃圾的强大神器!(清理安装残留文件/注册表)
大家都知道 Windows 在卸载软件时总是不够彻底,系统C盘总会留下大量难以辨别和清理的垃圾文件和临时文件,时间长了注册表也会变得非常臃肿,不仅浪费硬盘空间,而且也会明显拖慢系统响应和启动速度. R ...
- XCode8.3真机调试设置
本文使用XCode8.3.3 首先XCode->Preferncs,进入下面的界面 点击左下角“+”号,并输入账号,然后点击Manage Certificates,左下角添加IOS develo ...
- 学习Linux第一周记
2019/11/25 服务器硬件详述1) CPU 作用:运算/控制 关注信息 :路数 服务器中CPU的颗数 一般有 (单路 双路 ...
- Linux学习笔记(14)linux在6.x和7.x系列的安装与基本使用区别
关键词,centos7 centos6.x安装与使用:https://www.cnblogs.com/gered/p/9440551.html centos7.x安装与使用(本文)转自:https:/ ...
- Mybatis(二) SQL映射文件
SQL映射文件 单条件查询 1. 在UserMapper接口添加抽象方法 //根据用户名模糊查询 List<User> getUserListByName(); 2. 在UserMappe ...
- CGAL 属性配置
libgmp-10.lib libmpfr-4.lib boost_system-vc120-mt-gd-1_63.lib D:\dev\CGAL-4.9\include D:\dev\CGAL-4. ...
- [HAOI2018]苹果树题解
题目链接 大意:不解释 思路: 首先方案数共有n!种,第1个点只有1种选择,第2个点2种选择,生成2个选择的同时消耗一个,第3个点则有3种选择,依次类推共有n!种方案,由于最后答案*n!,故输出的实际 ...
- YII框架微信公众号
<?phpnamespace backend\controllers; use yii\db\Query;use yii\web\Controller;use Yii;class Exam2Co ...
- mysql5.6
5.6 与之后版本有差别本文以5.6为例** 1.mysql5.6安装 本文采用2进制安装 mkdir /server/tools -p cd /server/tools 1.下载 wget http ...
- python的类属性、实例属性、类方法、静态方法
类属性 就像如下代码: class Person: name = "张三" # 共有类属性 __age = 18 # 私有类属性 在类中直接定义的属性就是类属性,它被所有的实例对象 ...