AT_abc270_g [ABC270G] Sequence in mod P 题解

· · 题解

分析

大步小步算法(BSGS)

代码

#include <bits/stdc++.h>
#define int long long
#define inf 1e10
using namespace std;
int a, b, s, g, p;
int A, B, C;

inline void read(int &x) {
    char ch = x = 0;
    int m = 1;
    while (ch < '0' || ch > '9') ch = getchar();
    while (ch >= '0' && ch <= '9') {
        x = (x << 1) + (x << 3) + ch - 48;
        ch = getchar();
    }
    x *= m;
    return ;
}

inline void print(int x) {
    if (x < 0) putchar('-'), x = -x;
    static int stk[50];
    int top = 0;
    do {
        stk[top++] = x % 10;
        x /= 10;
    } while (x);
    while (top) {
        putchar(stk[--top] + 48);
    }
    putchar('\n');
    return ;
}

inline int ksmi(int a, int b, int p) {
    a %= p;
    int res = 1;
    while (b) {
        if (b & 1) res = res * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return res;
}

inline int BSGS(int a, int b, int p) {
    a %= p, b %= p;
    if (b == 1 || a == b) return b != 1;
    map<int, int> mp;
    int B = ceil(sqrt(p)), res = inf;
    for (int i = B; i; i--) {
        mp[ksmi(a, i * B, p)] = i * B;
    }
    for (int i = 0; i <= B; i++) {
        if (mp.find(b * ksmi(a, i, p) % p) != mp.end()) {
            res = min(res, mp[b * ksmi(a, i, p) % p] - i);
        }
    }
    if (res == inf) {
        return -1;
    } else {
        return res;
    }
}

signed main() {
    int T;
    read(T);
    while (T--) {
        read(p), read(a), read(b), read(s), read(g);
        if (s == g) print(0);
        else if (a == 0) {
            if (b == g) print(1);
            else print(-1);
        } else if (a == 1) {
            if (b == 0) print(-1);
            else {
                int x = ((g - s) % p + p) % p * ksmi(b, p - 2, p) % p;
                print(x);
            }
        } else if (s == 0 && b == 0) {
            print(-1);
        } else {
            A = a, C = ksmi(A - 1, p - 2, p) * b % p;
            B = ksmi(s + C, p - 2, p) * ((g + C) % p) % p;
            print(BSGS(A, B, p));
        }
    }
    return 0;
}