你被要求设计一个计算器完成以下三项任务:

1、给定y、z、p,计算y^z mod p 的值;

2、给定y、z、p,计算满足xy ≡z(mod p)的最小非负整数x;

3、给定y、z、p,计算满足y^x ≡z(mod p)的最小非负整数x。

为了拿到奖品,全力以赴吧!

思路:
对于询问1,快速幂解决

对于询问2,扩展欧几里得解决

对于询问3,采用BSGS算法

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll p, a, b;
ll qmul(ll a, ll b, ll mod) {
    ll ans = 0;
    while (b) {
        if (b & 1) {
            ans = (ans + a) % mod;
        }
        a = (a + a) % mod;
        b >>= 1;
    }
    return ans % mod;
}
ll qpow(ll a, ll b, ll mod) {
    ll ans = 1;
    while (b) {
        if (b & 1) {
            ans = (ans * a) % mod;
        }
        a = (a * a) % mod;
        b >>= 1;
    }
    return ans % mod;
}

ll exgcd(ll a, ll b, ll &x, ll &y) {
    if (!b) {
        x = 1; y = 0;
        return a;
    } else {
        ll d = exgcd(b, a % b, y, x);
        y -= a / b * x;
        return d;
    }
}

ll bsgs(ll a, ll b, ll p) {
    b%=p;a%=p;
    ll n = sqrt(p) + 1;
    map<ll,ll> mp;
    mp.clear();
    ll ans = b%p;
    if (a == 0 && b == 0) return 0;
    if (a == 0 && b != 0) return -1;
    for (int i = 0; i <= n; i++) {
        mp[ans] = i;
        ans = qmul(ans, a, p);
    }
    ans = 1;
    for (int i = 1; i <= n; i++) ans = qmul(ans, a, p);
    ll ret = 1;
    for (int i = 1; i <= n; i++) {
        ret = qmul(ret, ans, p);
        if (mp[ret] != 0) {
            return (ll)i * n - mp[ret];
        }
    }
    return -1;
}

int main() {
    int n, opt;
    ll a, b, p, x, y;
    while (scanf("%d%d", &n, &opt) != EOF) {
        for (int i = 1; i <= n; i++) {
            scanf("%lld%lld%lld", &a, &b, &p);
            if (opt == 1) {
                printf("%lld\n", qpow(a, b, p));
            } else if (opt == 2) {
                ll d = exgcd(a, p, x, y);
                if (b % d != 0) {
                    printf("Orz, I cannot find x!\n");
                } else {
                    x = qpow(a, p - 2, p) * b % p;
                    printf("%lld\n", x);
                }
            } else {
                ll ans = bsgs(a, b, p);
                if (ans == -1) {
                    printf("Orz, I cannot find x!\n");
                } else {
                    printf("%lld\n", ans);
                }
                
            }
        }
    }
    return 0;
}