【POJ3243】【拓展BSGS】Clever Y

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

Input data consists of no more than 20 test cases. For each test case, there would be only one line containing 3 integers X, Z, K (0 ≤ X, Z, K ≤ 109).
Input file ends with 3 zeros separated by spaces.

Output

For each test case output one line. Write "No Solution" (without quotes) if you cannot find a feasible Y (0 ≤ Y < Z). Otherwise output the minimum Y you find.

Sample Input

5 58 33
2 4 3
0 0 0

Sample Output

9
No Solution

Source

【分析】
时间卡得真紧TAT,被T出翔。
后面用HASH + 链表才过...
  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 }
View Code

 

posted @ 2015-03-20 10:04  TCtower  阅读(197)  评论(0编辑  收藏  举报