BSGS&EXBSGS
BSGS
求最小的非负整数\(x\)满足\(a^x\equiv{b}\pmod{p}\)(\(\gcd(a,p)=1\))
\[a^x\equiv{b}\pmod{p}
\]
令\(x=ti-k(t=\sqrt{p},k\in[0,t-1])\)
\[a^{ti-k}\equiv{b}\pmod{p}
\]
\[a^{ti}\equiv{b}*a^k\pmod{p}
\]
先枚举\(k\),将\(b*a^k\)的值存入\(hash\)表
再枚举\(i\in[1,t]\),若\((a^t)^i\)的值出现了,则\(x=i*t-k\)
EXBSGS
求最小的非负整数\(x\)满足\(a^x\equiv{b}\pmod{p}\)
- \(b=1,x=0\)
- \(a=0,b=0,x=1\)
- \(a=0,b\ne{0}\)无解,否则
\[a*a^{x-1}\equiv{b}\pmod{p}
\]
设\(d=(a,p)\),若\(d\nmid{b}\)无解,否则
\[\frac{a}{d}*a^{x-1}\equiv{\frac{b}{d}}\pmod{\frac{p}{d}}
\]
令\(A=a,B=\frac{b}{d},C=\frac{a}{d},P=\frac{p}{d}\),则
\[CA^{x}\equiv{B}\pmod{P}
\]
递归即可,当\(d=1\)时可直接\(BSGS\)
Code
int bsgs(int a, int b, int p, int c, int k)
{
hs.clear();
int q = 1, t = (int)(sqrt(p)) + 1;
for (int i = 0; i < t; i ++ )
{
hs[1ll * q * b % p] = i;
q = 1ll * q * a % p;
}
int cnt = q;
q = 1ll * q * c % p;
for (int i = 1; i <= t; i ++ )
{
if (hs.find(q) != hs.end()) return k + i * t - hs[q];
q = 1ll * q * cnt % p;
}
return -1;
}
int exbsgs(int a, int b, int p)
{
a %= p, b %= p; // 特别注意1
if (b == 1) return 0;
if (!a)
{
if (!b) return 1;
return -1;
}
int k = 0, A = a, B = b, C = 1, P = p, d = gcd(A, P);
while (d != 1)
{
if (B % d) return -1;
B /= d, P /= d, C = 1ll * C * (A / d) % P, k ++ ; // 特别注意2(除了d都是大写)
d = gcd(A, P);
if (C == B) return k; // 特别注意3
}
return bsgs(A, B, P, C, k);
}