BSGS算法

本文详细介绍了BabyStepGiantStep算法,一种用于求解特定类型离散对数问题的算法。通过将未知指数表示为两个较小部分的差,算法能够在平方根的时间复杂度内找到最小整数解。文章提供了算法的实现细节,包括如何利用哈希表优化查找过程,以及C++11中unordered_map的使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Baby Step Gaint Step算法

这个算法是解决什么的呢?
求关于 y y y的方程
x y ≡ z   (   m o d     p ) x^y\equiv z\ (\bmod\ p) xyz (mod p)
的最小整数解
其中保证 ( x , p ) = 1 (x,p)=1 (x,p)=1
其实还是挺暴力的…
为了便于解决,我们把 y y y表示成 i m − j im-j imj的形式
那么原来的式子就变成了
x i m − j ≡ z   (   m o d     p ) x^{im-j}\equiv z\ (\bmod\ p) ximjz (mod p)
x i m ≡ z ⋅ x j   (   m o d     p ) x^{im}\equiv z\cdot x^j\ (\bmod \ p) ximzxj (mod p)
那么我们枚举每一个 j ∈ [ 0 , m ] j\in[0,m] j[0,m],记录出 z ⋅ x j z\cdot x^j zxj的值
然后枚举每一个 i i i,看 x i m x^{im} xim的值之前有没有出现过,如果出现过就输出
如果一直没有出现过就无解
m m m显然取 p \sqrt{p} p 的时候复杂度最优,所以BSGS算法的复杂度是 O ( p ) O(\sqrt p) O(p )
但是注意记录的时候最好使用哈希,用STL的话不要用 m a p map map,因为 m a p map map会多一个 l o g log log
用STL就用unordered_map
但是这个东西c++11才有,如果编译器不能运行的话,在编译的时候加一行指令
-std=c++11
就可以啦

给出关键代码:

unordered_map<ll,ll> var;
ll BSGS(ll x,ll z){
	var.clear();
	ll m=ceil(sqrt(mod));
	for(ll i=0,j=z;i<=m;i++,j=j*x%mod)var[j]=i;
	for(ll i=1,j=Qpow(x,m),k=j;i<=m;i++,j=j*k%mod)if(var.count(j))return i*m-var[j];
	return -2;
}

模板题:
[SDOI2011]计算器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值