【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 ≤ 10 9).
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

POJ Monthly--2007.07.08, Guo, Huayang
【分析】
时间卡得真紧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

 

你可能感兴趣的:(poj)