pohlig-hellman算法讲解(有例子)
作者:互联网
写在前面
一切都要从去年8月的多校开始说起。
笔者在多校某场比赛中,遇到一个离散对数的题:HDU 6632
给定a,b,p(p∈prime,65537≤p≤1e18,2≤a,b≤p−1且p−1的质因子只能由2(和/或)3组成),求
ax≡b(mod p)
的最小正整数解,若无解则输出−1。
因为质数p很大,且通常使用的BSGS复杂度为O(n),显然无法通过正常方法解题。于是很理所应当地翻车了。
随后出题人给的题解中提到了 pohlig-hellman算法,想去学,但国内对于该算法的相关资料实在是少之又少。于是在理应不存在的404网站们找到了相关视频学习后才醒悟(一醒就是半年,咕咕咕)。于是决定整理一下这个问题。
注:笔者是一名十八线蒟蒻ACMer,因此下列文章可能有许多细节上的问题,请您指正,我将尽快回复和改正,非常感谢!
前置技能
快速幂
基础数论知识
欧拉函数
中国剩余定理(CRT)
质因子分解
pohlig-hellman算法
需要注意的是,pohlig-hellman算法的复杂度在一般情况下比BSGS高!
因此,使用pohlig-hellman的场合只能是较为特殊的情况。
p是质数,且p-1包含的质因子较少&较小。
(p不是质数有待补充。)
和BSGS算法一样,pohlig-hellman算法也是用于解决离散对数问题(也有很多文献提到是解决椭圆曲线之类的)。
即给定a,b,p,求ax≡b(mod p)。
在开始讲算法前,首先要提一下欧拉定理。
若(a,p)=1,那么aφ(p)≡1(mod p)⋅⋅⋅⋅⋅⋅(∗)
证明略。
如果p是质数,那φ(p)=p−1,即费马小定理。
接下来,开始将pohlig-hellman算法的步骤。
以下步骤建议读者自行手写一遍!
以下步骤建议读者自行手写一遍!
以下步骤建议读者自行手写一遍!
重要的话说三遍!
1.将φ(p)=p-1质因子分解
即p−1=p1k1p2k2...pmkm(m为质因子个数)
2.对于每个质因子pi,列出方程
x=pi0a0∗pi1a1∗pi2a2...∗piki−1aki−1(mod piki)
(即把x写成pi进制,每个系数都小于pi)。
3.令r=1,求(ax)pirp−1≡bpirp−1(mod p)
(注意这个pirp−1,这是我们求出ai各项系数的关键!)
4.展开x,得到(api0a0∗pi1a1∗pi2a2...∗piki−1aki−1)pirp−1≡bpirp−1(mod p)
5.展开,得(以下以r=1为例)
aa0∗pip−1∗a(p−1)a1∗(ap−1)pa2∗(ap−1)p2a3...(ap−1)p(ki−2)aki−1≡bpirp−1(mod p)
6.注意到从第二项开始,后面每一项都是1(因为由欧拉定理得ap−1≡1(mod p),1的任何次方都是1),故我们可以得到式子
aa0∗pip−1≡bpirp−1(mod p)
因为a_i的所有系数∈[0,pi−1](前文提到了pi进制),故可以在O(pi)的时间内暴力求出a0。
7.得到a0后,令r=r+1,回到步骤3。
直到所有a_i被求出后,可得到:
x=pi0a0∗pi1a1∗pi2a2...∗piki−1aki−1(mod piki)。
(注意模数不是p!)
8.在算出m个关于x的式子后,来一发CRT(中国剩余定理)即可(不需要扩展CRT,因为模数互质)。
需要注意!如果这组方程在CRT中无解,则说明原方程无解!!!
举例
下面,我们通过一个例子来帮助理解以上的步骤。
eg: 7x≡12(mod 41)
解:首先分解φ(41)=40=235。
对于质因子2,我们首先列出方程
x=20a0∗21a1∗22a2(ai∈[0,1])
在等式两边同乘以2p−1=20,得
7x20≡1220(mod 41)。
将x展开,得
7(20a0∗21a1∗22a2)20≡1220(mod 41)
化简,得
720a0∗740a1∗7802a∗≡1220(mod 41)
由费马小定理/欧拉定理得后面两项都是1,故:
720a0≡1220(mod 41)
快速幂优化,得
40a0≡40(mod 41)
在[0,1]内枚举a0,得到a0=1。
有了a1后,我们将原式同乘以22p−1=10,得到7x10≡1210(mod 41)。
重复上述步骤,得
7(1∗21a1∗22a2)10≡1210(mod 41)
化简,得
710∗720a1∗740a2≡1210(mod 41)
同样道理,后面一项是1,得
710∗720a1≡1210(mod 41)
快速幂优化,得
9∗40a1≡9(mod 41)
在[0,1]内枚举a1,得a1=0。
同理我们得到a2=1,于是x≡20∗1+21∗0+22∗1≡5(mod 8)
即x≡5(mod 8)
对于质因子5,同理,设x=50a0(ai∈[0,4]),得到a0=3,即x=3(mod 5)。
综上所述,我们得到:
{x≡5(mod 8)x≡3(mod 5)
由中国剩余定理可以得到x≡13(mod 40)。
对该算法的理解&复杂度计算
个人认为,pohlig-hellman是对欧拉定理深度理解后的一种体现,先是对于每个质因子qi,将其表示成qi进制的数字,为了便于后面不断地在等式两边同乘(p−1)/pir来使得部分项变成1消去,从而得到各项系数,最后CRT求解。
复杂度计算:
记ω(n)为n的质因子个数,Ω(n)定为每个质因数的幂次之和,
(对于420=22∗3∗5∗7,ω(n)=4,Ω(n)=2+1+1+1=5)
首先,质因子分解需要O(Ω(n))(原本是要先欧拉筛出质数,再质因子分解,但毕竟p-1的质因子很少时才能使用该算法(通常只有2,3,5,7),因此可以直接事先处理出来)。
其次,算出各类系数的复杂度为O(logn∗(Ω(n)))(每一个质因子系数是从0~对应次方-1的,再算上快速幂的复杂度)。
最后,还有中国剩余定理(CRT),其复杂度为O((ω(n)logω(n)))(CRT的复杂度有待确认)
综上,总复杂度为O(Ω(n)+logn∗Ω(n)+ω(n)logω(n))。
这也就是为什么,当p−1的质因子又小又少时,pohlig-hellman算法远远优于BSGS的原因。
代码
先咕咕咕,年后来写。好像CSDN上有别人写的来着…
后记
写这篇文章的动机很简单:我没看懂国内关于pohlig-hellman算法的文章(肯定是我语文差),因此在某些网站上学懂之后想着自己写一篇文章,一来是方便日后复习,二来帮助下和我语文一样差的程序猿…
其实p不是质数时,也是可适用该算法,只是笔者还需要一些时间来确认一些细节问题,故先咕咕咕,日后补上。
DrGilbert 2020.1.21
标签:...,hellman,41,pohlig,因子,讲解,20,mod,equiv 来源: https://blog.csdn.net/oampamp1/article/details/104061969