\(\\\)

BSGS


用于求解关于 \(x\) 的方程:

\[a^x\equiv b\pmod p\ ,\ (p,a)=1
\]

一般求解的是模意义下的指数,也就是最小非负整数解。

\(\\\)

算法思想


本质是双向搜索,或阈值优化的思想。

首先设"步幅" 为 \(m=\lceil{ \sqrt p}\rceil\) ,然后将方程写作

\[a^{i\times m-j}\equiv b\pmod p
\]

其中 \(i\) 就是所谓"大步", \(j\) 就是所谓"小步",我们要把他们组合在一起。

直接搜索两个数不如折半搜索一个数,然后再组合。

于是我们可以将分母上的 \(a^j\) 移项,得到

\[a^{i\times m}\equiv b\times a^j\pmod p
\]

然后就成了比较标准的双向搜索形式。

先把右一半的答案记下来,然后拿左一半搜到的每一个数去查询是否出现过就好了。

\(\\\)

代码实现


对于每一个 \(j\in [0,m-1]\) ,将 \(b\times a^j\ \%\ p\) 的答案放到哈希表里。

然后对于每一个 \(i\in[1,m](\) 此范围依据定义而来,尤其注意!\()\),去哈希表里查是否有 \(a^{im}\ \%\ p\) 的值。

还有两个小优化:

  • 注意到求出为同一个值的 \(j\) ,因为在答案里系数为 \(-1\) ,所以对于求出最小解 \(j\) 肯定是越大越优秀。

    因此再哈希表里插入相同的值时,可以直接取 \(max\), 如果是按序插入直接覆盖即可。

    这里也延申出了一种做法,直接用 \(map\) 存储结果,将结果映射到 \(j\) ,按序插入直接覆盖,复杂度多个\(log\) 。

  • 运算过程中只需一次快速幂。

    一开始每一次都是乘上 \(a\) ,所以一遍循环一遍乘即可,第二步同理,只需题前计算出 \(a^m\) 的值。

    这一优化在需要快速乘的时候效果很好。

我们以 [TJOI2007]可爱的质数 一题为例提供一份模板。

#include<map>
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define R register
using namespace std;
typedef long long ll; map<ll,ll> s; inline ll qpow(ll x,ll t,ll p){
ll res=1;
while(t){
if(t&1) (res*=x)%=p;
(x*=x)%=p; t>>=1;
}
return res;
} inline ll BSGS(ll a,ll b,ll p){
b%=p;
ll m=ceil(sqrt(p));
for(R ll i=0;i<m;++i,(b*=a)%=p) s[b]=i;
a=qpow(a,m,p);
for(R ll i=1,tmp=a;i<=m;++i,(tmp*=a)%=p)
if(s.find(tmp)!=s.end()){
if(i*m<s[tmp]) continue;
return i*m-s[tmp];
}
return -1;
} int main(){
ll a,b,p;
scanf("%lld%lld%lld",&p,&a,&b);
ll x=BSGS(a,b,p);
if(x>=0) printf("%lld\n",x);
else puts("no solution");
return 0;
}

最新文章

  1. Asp.net WebAPI 单元测试
  2. OC2-xml文件解析
  3. 在Windows下编译FFmpeg详细说明
  4. POJ 2411 压缩状态DP
  5. smbpasswd命令常用选项
  6. 爬虫代码实现五:解析所有分页url并优化解析实现类
  7. html5中拨打电话代码
  8. 2017全球互联网技术大会回顾(附PPT)
  9. 基于.NET CORE微服务框架 -谈谈surging的服务容错降级
  10. Docker学习笔记 - Docker的远程访问
  11. [转] XEN, KVM, Libvirt and IPTables
  12. 线性代数的本质与几何意义 02. 线性组合、张成的空间、基(3blue1brown 咪博士 图文注解版)
  13. BZOJ4448[Scoi2015]情报传递——主席树+LCA
  14. 图片的Base64编码
  15. mysql caching_sha2_password异常分析
  16. El表达式对照表
  17. android小程序-电子钢琴-多点触控
  18. Django商城项目笔记No.17用户部分-用户中心用户地址管理
  19. 图学ES6-5.正则的扩展
  20. nginx添加认证

热门文章

  1. 减治算法之寻找第K小元素问题
  2. windows 目录空格
  3. js数组清空和去重
  4. Linux设备驱动--块设备(四)之“自造请求”
  5. 【转】浏览器中输入url后发生了什么
  6. 获取http请求的响应状态
  7. artemplate include
  8. 关于ArcGis for javascript的使用
  9. HDU 5907 Find Q (水题)
  10. mybatise