浅谈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, ...
随机推荐
- Django框架中使用Echart进行统计的SQL语句
最近想用Echart做数据统计的图形显示,数据来源是MySQL数据库,自然需要根据不同的搜索条件筛选出表中的数据,用比较多的就是时间的参数吧! 常用的mysql时间的条件进行检索的SQL语句: 数据表 ...
- [转帖]/proc/sys/net/ipv4/ 下参数理解
/proc/sys/net/ipv4/ 下参数理解,方便服务器优化 2017年06月02日 16:52:27 庞叶蒙 阅读数 3065 https://blog.csdn.net/pangyemeng ...
- React基础篇学习
到今天为止, 使用react已经一年了, 现在整理一下入门时的一些重要知识, 帮助想要学习react的同学们理解某些内容. React 元素 React 元素,它是 React 中最小基本单位,我们可 ...
- Node.js 博客搭建
Node.js 博客搭建:https://www.linuxidc.com/Linux/2017-02/140115.htm https://www.cnblogs.com/mrcln/p/93087 ...
- [gym101981M][2018ICPC南京M题]Mediocre String Problem
题目链接 题目大意是问在$S$串中找区间$[i,j]$,在$T$串中找位置$k$,使得$S[i,j]$和$T[1,k]$可以组成回文串,并且$j-i+1>k$,求这样的三元组$(i,j,k)$的 ...
- POJ 2492 A Bug's Life 题解
题面 这道题是一道标准的种类并查集: 种类并查集是给每个结点一个权值.然后在合并和查找的时候根据情况对权值来进行维护. 通过将原有的区间范围变大使并查集可以维护种类的联系: #include < ...
- BZOJ 1257 余数之和 题解
题面 这道题是一道整除分块的模板题: 首先,知道分块的人应该知道,n/i最多有2*sqrt(n)种数,但这和余数有什么关系呢? 注意,只要n/i的值和n/(i+d)的值一样,那么n%i到n%(i+d) ...
- vmware中的虚拟linux配置多块网卡
在使用vm上运行多个linux系统,来模拟LVS负载均衡实验中.需要在lvs服务器中设置两块网卡,发现可以在vm给虚拟机添加任意多个网卡. 方法: 不要启动Linux,在上面的菜单项中选择: “VM— ...
- POJ 3249 Test for Job (拓扑排序+DP)
POJ 3249 Test for Job (拓扑排序+DP) <题目链接> 题目大意: 给定一个有向图(图不一定连通),每个点都有点权(可能为负),让你求出从源点走向汇点的路径上的最大点 ...
- BZOJ 3118 Orz the MST
权限题qwq 如果我们要使得某棵生成树为最小生成树,那么上面的边都不能被替代,具体的,对于一个非树边,它的权值要\(\ge\)它两端点在树上的路径上的所以边的权值,所以对于每个非树边就可以对一些树边列 ...