BSGS算法

给定一个质数 p,以及正整数 a,b,求满足同余方程 \(a^x=b(mod p)\)的最小非负整数x,无法满足时输出-1.

如果只是简单的枚举 x,那么要想得出结论,由于循环节最大为 \(p-1\)(欧拉定理),就需要枚举 0~p-1 去验证答案,当 p 的数量级达到 10^9 时,这种枚举显然不能满足算法时间复杂度的需求了。

推导过程

首先令\(x=A\times \lceil \sqrt{p} \rceil - B\),其中,\(0\leq A,B \leq \lceil \sqrt{p} \rceil\),将其代入方程得:\(a^{A\times \lceil \sqrt{p} \rceil - B}=b(mod p)\),

移项得\(a^{A\times \lceil \sqrt{p} \rceil}=b\times a^B(mod p)\)

分析这个方程可知:a,b已知,枚举A,B来计算方程的解.

先枚举B,将方程右边的结果存入哈希表中,在枚举A,若出现的值存在于哈希表中,可以通过\(x=A\times \lceil \sqrt{p} \rceil - B\),

得到方程的解.

时间复杂度\(O(\sqrt{p} \log{\sqrt{p}})\)

(对于引入中的问题,只要在枚举 A 的过程中发现值与右端中某个值相等,那么就可以直接返回 x,因为在 A 的增大过程中,x 是逐渐增大的,因此第一次找到相等情况的就是答案)

ll bsgs(ll a, ll b, ll mod)
{
    map<ll, ll> mp;
    ll cur = 1, t = sqrt(mod) + 1;
    for(int B = 1; B <= t; B++)
    {
        cur = cur * a % mod;
        mp[b * cur % mod] = B;
    }
    ll now = cur;
    for(int A = 1; A <= t; A++)
    {
        if(mp[now]) 
            return (ll)A * t - mp[now];
        now = now * cur % mod;
    }
    return -1;
}
posted on 2022-06-28 00:04  naiji  阅读(100)  评论(0编辑  收藏  举报