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);
}
posted @ 2021-03-16 16:59  andysj  阅读(65)  评论(0编辑  收藏  举报