Description
Little Y finds there is a very interesting formula in mathematics:
XY mod Z = K
Given X, Y, Z, we all know how to figure out K fast. However, given X, Z, K, could you figure out Y fast?
Input
Output
Sample Input
5 58 33 2 4 3 0 0 0
Sample Output
9 No Solution
Source
1 /* 2 五代李煜 3 《浪淘沙令·帘外雨潺潺》 4 帘外雨潺潺,春意阑珊。罗衾不耐五更寒。梦里不知身是客,一晌贪欢。 5 独自莫凭栏,无限江山,别时容易见时难。流水落花春去也,天上人间。 6 */ 7 #include <iostream> 8 #include <cstdio> 9 #include <ctime> 10 #include <cmath> 11 #include <algorithm> 12 #include <cstring> 13 #include <string> 14 #include <map> 15 #include <set> 16 #include <vector> 17 #define LOCAL 18 const int MAXN = 1000 + 10; 19 const int maxn = 65535;//用来HASH 20 const int INF = 0x7fffffff; 21 using namespace std; 22 typedef long long ll; 23 struct Hash{ 24 ll a,b,next; 25 }Hash[maxn << 1]; 26 ll flg[maxn + 66]; 27 ll top,idx; 28 void ins(ll a,ll b){ 29 ll k = b & maxn; 30 if (flg[k] != idx){ 31 flg[k] = idx; 32 Hash[k].next = -1; 33 Hash[k].a = a; 34 Hash[k].b = b; 35 return ; 36 } 37 while (Hash[k].next != -1){ 38 if(Hash[k].b == b) return ; 39 k = Hash[k].next; 40 } 41 Hash[k].next = ++ top; 42 Hash[top].next = -1; 43 Hash[top].a = a; 44 Hash[top].b = b; 45 } 46 ll find(ll b){ 47 ll k = b & maxn; 48 if (flg[k] != idx) return -1; 49 while (k != -1){ 50 if(Hash[k].b == b) return Hash[k].a; 51 k = Hash[k].next; 52 } 53 return -1; 54 } 55 ll gcd(ll a,ll b) {return b == 0? a: gcd(b, a % b);} 56 ll exgcd(ll a, ll b, ll &x, ll &y){ 57 if (b == 0){x = 1; y = 0; return a;} 58 ll tmp = exgcd(b, a % b, y, x); 59 y -= x * (a / b); 60 return tmp; 61 } 62 //求解线性同余方程 形如Ax = B(mod C) 63 ll solve(ll a, ll b, ll c){ 64 ll x, y, Ans; 65 ll tmp = exgcd(a, c, x, y); 66 Ans = (ll)(x * b) % c; 67 return Ans >= 0 ? Ans : Ans + c; 68 } 69 ll pow(ll a, ll b, ll c){ 70 if (b == 1) return a % c; 71 ll tmp = pow(a, b / 2, c); 72 if (b % 2 == 0) return (tmp * tmp) % c; 73 else return (((tmp * tmp) % c) * a) % c; 74 } 75 ll BSGS(ll A, ll B, ll C){ 76 top = maxn; 77 ++idx; 78 ll buf = 1 % C, D = buf, K, tmp; 79 for (ll i = 0; i <= 100; i++){ 80 if (buf == B) return i; 81 buf = (buf * A) % C; 82 } 83 ll d = 0; 84 while ((tmp = gcd(A, C)) != 1){ 85 if (B % tmp != 0) return -1; 86 d++; 87 B /= tmp; 88 C /= tmp; 89 D = D * A / tmp % C; 90 } 91 //hash表记录1-sqrt(c)的值 92 ll M = (ll)ceil(sqrt(C * 1.0)); 93 buf = 1 % C; 94 for (ll i = 0; i <= M; i++){ 95 ins(i, buf); 96 buf = (buf * A) % C; 97 } 98 K = pow(A, M, C); 99 for (ll i = 0; i <= M; i++){ 100 tmp = solve(D, B, C); 101 ll w; 102 if (tmp >= 0 && (w = find(tmp)) != -1) return i * M + w + d; 103 D = (D * K) % C; 104 } 105 return -1; 106 } 107 108 int main(){ 109 110 ll A, B, C; 111 while (scanf("%lld%lld%lld", &A, &C, &B) != EOF){ 112 if (A == 0 && C == 0 && B == 0) break; 113 B %= C; 114 ll tmp = BSGS(A, B, C); 115 if (tmp >= 0) printf("%lld\n", tmp); 116 else printf("No Solution\n"); 117 } 118 return 0; 119 }