BSGS
求最小的非负整数(x)满足(a^xequiv{b}pmod{p})((pin{P}))
[a^xequiv{b}pmod{p}
]
令(x=ti-k(t=sqrt{p},kin[0,t-1]))
[a^{ti-k}equiv{b}pmod{p}
]
[a^{ti}equiv{b}*a^kpmod{p}
]
先枚举(k),将(b*a^k)的值存入(hash)表
再枚举(iin[1,t]),若((a^t)^i)的值出现了,则(x=i*t-k)
EXBSGS
求最小的非负整数(x)满足(a^xequiv{b}pmod{p})
- (b=1,x=0)
- (a=0,b=0,x=1)
- (a=0,b e{0})无解,否则
[a*a^{x-1}equiv{b}pmod{p}
]
设(d=(a,p)),若(d mid{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);
}