大步小步算法是专门用来求解a^x = b(mod n)这种方程的,这种问题也称为离散对数问题。
已知a,b,n,且n为素数,求x。
模板如下
#include <iostream>
#include <cstdio>
#include <map>
using namespace std;
typedef long long LL;
LL quick_mod(LL a, LL b, LL c)//费马小定理+快速幂求逆元
{
LL ans = 1;
while (b)
{
if (b % 2 == 1)
ans = (ans*a) % c;
b /= 2;
a = (a*a) % c;
}
return ans;
}
int log_mod(int a, int b, int n)
{
int m, v, e = 1, i;
m = (int)sqrt(n + 0.5);
v = quick_mod(quick_mod(a, m, n),n-2, n);
map<int, int> x;
x[1] = 0;
for (int i = 1; i < m; i++) {
e = e*a%n;
if (!x.count(e)) x[e] = i;
}
for (i = 0; i < m; i++) {
if (x.count(b)) return i*m + x[b];
b = b*v%n;
}
return -1;
}
如果无解,则返回-1。