浅谈BSGS&exBSGS

概(che)论(dan)

BSGS又称拔山盖世算法
Baby Step Giant Step
又称求离散对数
一般用于给出 a , b , p a, b, p a,b,p

a x ≡ b ( m o d p ) a^x \equiv b \pmod p axb(modp)

算法流程

比较简单,其实就是分块,小块的暴力预处理,然后一块一块跳
借用 psk011102 的图
浅谈BSGS&exBSGS_第1张图片

大概就是这样
先丢个板子题吧:
代码实现很简单:

#include
#define ll long long
using namespace std;
ll p, b, n, mod;
map<ll, ll> mp;
ll qpow(ll x, int y) {
	ll ret = 1;
	for(; y; y >>= 1, x = x * x % mod) if(y & 1) ret = ret * x % mod;
	return ret;
}
int BSGS(int p, int b, int n) {
	int m = sqrt(p) + 1; ll t = n; mod = p;
	for(int i = 0; i <= m; i ++, t = t * b % mod) mp[t] = i;//先把<=m的丢进map里面
	ll tt = qpow(b, m); t = tt;//每次跳m个
	if(!tt) return n == 0? 1 : -1;//特判0
	int f = 0;
	for(int i = 1; i <= m + 1; i ++, t = t * tt % mod) {
		int j = mp.find(t) == mp.end()? -1 : mp[t];
		if(j >= 0) return i * m - j;//如果找到了就返回
	}
	return -1;	
}
int main() {
	scanf("%lld%lld%lld", &p, &b, &n);
	int l = BSGS(p, b, n);
	if(l == -1) printf("no solution");
	else printf("%d ", l);
	return 0;
}

是不是很简单!!!
要注意这里必须满足 a ⊥ p a \perp p ap

如果不满足呢?

exBSGS

待填坑……

你可能感兴趣的:(数论,BSGS)