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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <map> #define ll long long ll qpow(ll a , ll b , ll m) { ll res = 1; while (b) { if (b & 1) res = (res * a) % m; b >>= 1; a = (a * a) % m; } return res % m; } ll exgcd(ll a , ll b , ll &x , ll &y) { if (!b) { x = 1; y = 0; return a; } ll d = exgcd(b , a % b , x , y); ll z = x; x = y; y = z - y * (a / b); return d; } bool le(ll a , ll b , ll c , ll &x , ll &y) { ll d = exgcd(a , b , x , y); if (c % d) return 0; ll k = c / d; x *= k; y *= k; return 1; } ll bsgs(ll a , ll b , ll p) { std::map <ll , ll> h; h.clear(); b %= p; ll t = sqrt(p) + 1; for (int i = 0 ; i < t ; i++) { ll v = b * qpow(a , i , p) % p; h[v] = i; } a = qpow(a , t , p); if (a == 0) return (b == 0) ? 1 : -1; for (int i = 0 ; i <= t ; i++) { int v = qpow(a , i , p); int j = h.find(v) == h.end() ? -1 : h[v]; if (j >= 0 && i * t - j >= 0) return i * t - j; } return -1; } ll n , y , z , k , m , x , flag , p; int main() { scanf("%lld%lld" , &n , &flag); for (int i = 1 ; i <= n ; i++) { scanf("%lld%lld%lld" , &y , &z , &p); if (flag == 1) { printf("%lld" , qpow(y , z , p)); } if (flag == 2) { if (le(y , p , z , x , m)) { printf("%lld" , (x % p + p) % p); } else { printf("Orz, I cannot find x!"); } } if (flag == 3) { if (bsgs(y , z , p) == -1) { printf("Orz, I cannot find x!"); } else { printf("%lld" , bsgs(y , z , p)); } } puts(""); } }
|