大步小步算法学习笔记
一、BSGS 算法
系统来说,它适用于求离散对数,也就是高次同余方程的解。
给定一个整数
首先,我们发现
考虑用哈希处理。我们将
用 map
实现的话,时间复杂度是
map<ll,ll>a;
ll p,b,s,v,w=1,x=1;
int main(){
p=read();b=read();v=read();
s=sqrt(p)+1;
for(ll i=0;i<s;i++){
if(!a[v])a[v]=i+1;
v=v*b%p;x=x*b%p;
}
for(ll i=1;i<=s;i++){
w=w*x%p;
if(a[w]){
cout<<i*s-a[w]+1<<'\n';
return 0;
}
}
cout<<"no solution\n";
return 0;
}
当然更优复杂度是用 gp_hash_table
实现的,时间复杂度
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
gp_hash_table<ll,ll>a;
二、exBSGS 算法
如果
那我们努力使得
gp_hash_table<ll,ll>q;
inline ll BSGS(ll a,ll b,ll p,ll c){
q.clear();
ll u=1,v=b,w=c,s=sqrt(p)+1;
for(ll i=0;i<s;i++){
q[v]=i+1;
v=v*a%p;u=u*a%p;
}
for(ll i=1;i<=s;i++){
w=w*u%p;
if(q[w])return i*s-q[w]+1;
}
return -1;
}
inline ll exBSGS(ll a,ll b,ll p){
a%=p;b%=p;
if(p==1||b==1)return 0;
ll cnt=0,g,ax=1,qwq;
while((g=__gcd(a,p))!=1){
if(b%g)return -1;
p/=g;cnt++;b/=g;
ax=ax*(a/g)%p;
if(ax==b)return cnt;
}
return ((qwq=BSGS(a,b,p,ax))==-1)?-1:cnt+qwq;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)