POJ 3243 Clever Y (求X^Y mod Z = K)
阿新 • • 發佈:2019-01-27
Clever Y
, Z, K (0 ≤ X, Z, K ≤ 109).
Input file ends with 3 zeros separated by spaces.
Time Limit: 5000MS | Memory Limit: 65536K |
Total Submissions: 7301 | Accepted: 1807 |
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 XInput 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
9No Solution
套模板
#include<stdio.h> #include<string.h> #include<math.h> #include <iostream> #include<stdlib.h> #include <algorithm> using namespace std; #define CC(m ,what) memset(m , what , sizeof(m)) typedef __int64 LL ; LL A, B ,C ; const int NN = 99991 ; bool hash[NN] ; int idx[NN] , val[NN] ; void insert(int id , LL vv) { LL v = vv % NN ; while( hash[v] && val[v]!=vv) { v++ ; if(v == NN) v-=NN ; } if( !hash[v] ) { hash[v] = 1; val[v] = vv ; idx[v] = id ; } } int find(LL vv) { LL v = vv % NN ; while( hash[v] && val[v]!=vv) { v++ ; if(v == NN) v-=NN ; } if( !hash[v] ) return -1; return idx[v] ; } void ex_gcd(LL a , LL b , LL& x , LL& y) { if(b == 0) { x = 1 ; y = 0 ; return ; } ex_gcd(b , a%b , x, y) ; LL t = x ; x = y; y = t - a/b*y ; } LL gcd(LL a,LL b) { while( a%b != 0) { LL c = a ; a = b ; b = c % b ; } return b ; } LL baby_step(LL A, LL B , LL C) { LL ans = 1 ; for(LL i=0; i<=50; i++) { if(ans == B) return i ; ans = ans * A % C ; } LL tmp , d = 0 ; LL D = 1 % C ; while( (tmp=gcd(A,C)) != 1 ) { if(B % tmp) return -1 ; d++ ; B/=tmp ; C/=tmp ; D = D*A/tmp%C ; } CC( hash , 0) ; CC( idx, -1) ; CC(val , -1) ; LL M = ceil( sqrt(C*1.0) ) ; LL rr = 1 ; for(int i=0; i<M; i++) { insert(i, rr) ; rr = rr * A % C ; } LL x, y ; for(int i=0; i<M; i++) { ex_gcd(D, C , x, y) ; LL r = x * B % C; r = (r % C + C) % C ; int jj = find( r ) ; if(jj != -1) { return LL(i)*M + LL(jj) + d ; } D = D * rr % C ; } return -1 ; } int main() { while(scanf("%I64d %I64d %I64d",&A,&C,&B) == 3) { if(A+B+C == 0 ) break ; LL res = baby_step(A,B,C) ; //A%C==B; if( res == -1 ) { printf("No Solution\n"); continue ; } printf("%I64d\n",res); } return 0 ; }