gmpy/离散对数
前几天做一个解离散对数的题用到了 gmpy,它是 GMP 的 Python 封装,用来算大数。
这里记两笔。首先是大整数需要用 mpz
对象,例如:
p = mpz(13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084171)
判断大数是否是质数:is_prime(p)
(求离散对数其实用不着)
求逆元 :invert(x, p)
。例如, y = invert(x, p)
则
幂取模:pow(x, n, p)
,即 。结果仍为 mpz。
mpz
对象可以直接用在 dict
中做键值。
题目中提供的方法是分治,将解 拆成两部分 ,其中是2的整数次方幂(约为上限的开方,例如,如果的范围是,则。这样 , 分别小于 ,将方程整理成 , 分别在等式左右(其它部分都是常数了),然后穷举 对应的值(计算次,保存所有结果),然后穷举所有的 对应的值,如果发现之前保存的结果中有匹配,则输出对应的 , ,从而算出 。由于将搜索范围变成了 ,所需的时间也就大大减少了。