Evaluate a ^ x = B (% C)
X = I * m + J (0 <= I <m, 0 <= j <m) M = Ceil (SQRT (c ));
Hash [I] === a ^ I % C
Then enumerate I to make AA = (a ^ m) ^ I
That is, the initial formula is changed to AA * a ^ J = B (% C)
If a ^ J is X, it becomes AA * x = B (% C). Then we can use the Extended Euclidean to calculate X.
Then, for X, go to the hash table to check whether the table exists.
# Include <iostream>
# Include <stdio. h>
# Include <vector>
# Include <queue>
# Include <stack>
# Include <string. h>
# Include <algorithm>
# Include <math. h>
Using namespace STD;
# Define ll long
# Define lcm (a, B) (a * B/gcd (a, B ))
// O (n) calculates the prime number, and 1-N is the Euler's number.
# Define n 1500001
Struct math_use
{
Ll run_exgcd (ll a, LL B, ll & X, ll & Y)
{
If (B = 0)
{
X = 1;
Y = 0;
Return;
}
Ll _ r = run_exgcd (B, A % B, x, y );
Ll T = X;
X = y;
Y = T-A/B * Y;
Return _ R;
}
Ll exgcd (ll a, LL B, ll C, ll & X, ll & Y)
{
Ll p = run_exgcd (a, B, x, y );
If (C % P) Return-1;
X = (x * C/P) % B;
Ll T = B/P;
X = (X % T + T) % T;
Return P;
}
Ll q_mod (ll a, LL B, ll N)
{
Ll ret = 1;
Ll TMP =;
While (B)
{
// The base already exists.
If (B & 0x1) ret = RET * TMP % N;
TMP = TMP * TMP % N;
B> = 1;
}
Return ret;
}
} M;
Struct hash_use
{
Ll X;
Int IP address;
Friend bool operator <(const hash_use & A, const hash_use & B)
{
If (A. X! = B. X) return a. x <B. X;
Else return a. IP <B. IP;
}
} Hash [110000];
Int select (ll x, int m)
{
Int L = 0;
Int r = m + 1;
Int mid = (L + r)/2;
While (L <R)
{
If (hash [Mid]. x> = x) r = mid;
Else l = Mid + 1;
Mid = (L + r)/2;
}
If (hash [Mid]. X! = X) Return-1;
Return hash [Mid]. IP;
}
Ll DoS (ll a, LL B, ll C)
{
Ll M = Ceil (SQRT (c ));
Memset (hash, 0, sizeof (hash ));
For (INT I = 0; I <= m; I ++)
{
Hash [I]. x = M. q_mod (A, I, C );
Hash [I]. IP = I;
}
Sort (hash, hash + m + 1 );
Ll s = M. q_mod (a, m, C );
For (INT I = 0; I <= m; I ++)
{
Ll AA = M. q_mod (S, I, C );
Ll X, Y;
M. exgcd (AA, C, B, x, y );
Int sel = select (x, M );
If (SEL! =-1)
{
Return I * m + sel;
}
}
Return-1;
}
Int main ()
{
Ll p, G, Y;
While (CIN> P> G> Y)
{
Ll ans = DoS (G, Y, P );
If (ANS =-1) cout <"error" <Endl;
Else cout <ans <Endl;
}
Return 0;
}