Baby-Step Giant-Step

# BSGS

求解 atb(modp)gcd(a,p)=1a^t\equiv b(mod\;p)\quad gcd(a,p)=1

由于欧拉定理 aϕ(p)1(modp)a^{\phi(p)}\equiv1(mod\;p)
也就是 ataxmodϕ(p)(modp)a^t\equiv a^{x\;mod\;\phi(p)}(mod\;p) 从而得到 t[0,ϕ(p)1]t\in[0,\phi(p)-1]
而我们在 [0,p][0,p] 里面求解,使 k=pk=⌈p⌉
此时 t=kxy,{1xk,0yk1}t=kx−y,\{1≤x≤k,0≤y≤k−1\}
问题转化问求 akxyb(modp)a^{kx−y}≡b(mod\;p)
akxbay(modp)a^{kx}≡b⋅ay(mod\;p)
使用hash表存入 bay(modp)b⋅ay(mod\;p) ,然后枚举 a^{kx} 看看hash表内有没有这个值

int bsgs(int a, int b, int p) {
    if (1 % p == b % p)
        return 0;
    int k = sqrt(p) + 1;
    unordered_map<int, int> hash;
    for (int i = 0, j = b % p; i < k; i++) {
        hash[j] = i;
        j = (ll)j * a % p;
    }
    int ak = 1;
    for (int i = 0; i < k; i++)
        ak = (ll)ak * a % p;
    for (int i = 1, j = ak; i <= k; i++) {
        if (hash.count(j))
            return (ll)i * k - hash[j];
        j = (ll)j * ak % p;
    }
    return -1;
}
int main() {
    int a, p, b;
    while (cin >> a >> p >> b, a || p || b) {
        int res = bsgs(a, b, p);
        if (res == -1)
            puts("No Solution");
        else
            cout << res << endl;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 扩展BSGS

求解 atb(modp)gcd(a,p)1a^t≡b(mod\;p)\quad gcd(a,p)\neq1

{a0b(modp),t=0a0!=b(modp),gcd(a,p)=d{d=1,BSGS直接求解d>1,atb(modp)at+kp=b(d%b0,无解返回)adat1+kpd=bdadat1bd(modpd)at1bdad1(modpd){if(gcd(at1,pd))=1BSGS直接求解else继续递归\left\{\begin{aligned} &a^0\equiv b(mod\;p),t=0\\ &a^0\;!= b(mod\;p),设gcd(a,p)=d \left\{\begin{aligned} &d=1,\quad BSGS直接求解\\ \\ &d>1,\quad\begin{aligned} ​ &a^t\equiv b(mod\;p)\\ ​ &a^t+kp=b\quad (若d\% b\ne0,无解返回) \\ ​ &\frac ad·a^{t-1}+k\frac pd=\frac bd\\ ​ &\frac ad·a^{t-1}\equiv \frac bd(mod\;\frac pd)\\ ​ &a^{t-1}\equiv\frac bd·\frac ad^{-1}(mod\;\frac pd) \left\{\begin{aligned} &if(\;gcd(a^{t-1},\frac pd)\;)=1\quad &BSGS直接求解\\ &else\quad&继续递归 \end{aligned}\right. \end{aligned} \end{aligned}\right. \end{aligned}\right.

const int INF = 1e8;
int exgcd(int a, int b, int &x, int &y) {
    if (!b) {
        x = 1, y = 0;
        return a;
    }
    int d = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}
int bsgs(int a, int b, int p) {
    if (1 % p == b % p)
        return 0;
    int k = sqrt(p) + 1;
    unordered_map<int, int> hash;
    for (int i = 0, j = b % p; i < k; i++) {
        hash[j] = i;
        j = (ll)j * a % p;
    }
    int ak = 1;
    for (int i = 0; i < k; i++)
        ak = (ll)ak * a % p;
    for (int i = 1, j = ak; i <= k; i++) {
        if (hash.count(j))
            return i * k - hash[j];
        j = (ll)j * ak % p;
    }
    return -INF;
}
int exbsgs(int a, int b, int p) {
    b = (b % p + p) % p; // b变成正的
    if (1 % p == b % p)
        return 0;
    int x, y;
    int d = exgcd(a, p, x, y);
    if (d > 1) { // a与p不互质,继续递归
        if (b % d)
            return -INF;                                          // 若b不是gcd的倍数
        exgcd(a / d, p / d, x, y);                                // exgcd求逆元
        return exbsgs(a, (ll)b / d * x % p % (p / d), p / d) + 1; // 因为本来求的是t-1的最小值,+1得t
    }
    return bsgs(a, b, p);
}
int main() {
    int a, p, b;
    while (cin >> a >> p >> b, a || p || b) {
        int res = exbsgs(a, b, p);
        if (res == -INF)
            puts("No Solution");
        else
            cout << res << endl;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

# 例题应用

给定一个🍅,xn=axn1+bx_n=ax_{n−1}+b ,已知 x1,a,bx_1,a,b ,求最早出现 xn=tx_n=tnn 是多少

由🍅可以看出,这是一个带常数项等比数列的公式,所以化为
xn+C=a×(xn1+C)(C=ba1)x_n+C=a\times(x_{n-1}+C)\quad(C=\frac{b}{a-1})
xn=a×xn1+C×(a1)x_n=a\times x_{n-1}+C\times(a-1)

xn+ba1=a×(xn1+ba1)=a2×(xn2+ba1)...=an1(x1+ba1)\begin{aligned} x_n+\frac{b}{a-1}&=a\times(x_{n-1}+\frac{b}{a-1})\\&=a^2\times(x_{n-2}+\frac{b}{a-1})\\&...\\&=a^{n-1}(x_1+\frac{b}{a-1})\end{aligned}

xn+ba1an1×(x1+ba1)(modp)\therefore x_n+\frac{b}{a-1}\equiv a^{n-1}\times(x_1+\frac{b}{a-1})(mod\;p)
xn=tx_n=t 时,an1t+ba1x1+ba1(modp)a^{n-1}\equiv \frac{t+\frac{b}{a-1}}{x_1+\frac{b}{a-1}}(mod\;p)
b=t+ba1x1+ba1(modp),an1b(modp)b'=\frac{t+\frac{b}{a-1}}{x_1+\frac{b}{a-1}}(mod\;p),\therefore a^{n-1}\equiv b'(mod\;p) BSGS去解即可

⚠️:若 (x1+a1b)0(modp)(x_1+\frac{a−1}{b})≡0(mod\;p) ,我们不能取逆元直接求解,但是可以发现倒数第三步的 an1(x1+ba1)a^{n−1}(x_1+\frac{b}{a-1}) 在余 pp 时为 00,可以直接特判掉

思路总结 等比数列公式可以化为 xnx_nx1x_1 的关系
因公比存在所以必定有一个幂次方且与 nn 有关
nn 即是我们要求的值,指数有 nn 的话求指数
问题即可使用BSGS解

Last Updated: 10/14/2023, 7:51:49 PM