http://poj.org/problem?id=3243
求A^x = B(mod C)中的x ,C是任意的数。
框架都在这里了:http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4
理解:http://blog.csdn.net/ivan_zjj/article/details/7597109
#include <stdio.h> #include <iostream> #include <map> #include <set> #include <list> #include <stack> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #include <algorithm> #define LL long long #define _LL __int64 #define eps 1e-12 #define PI acos(-1.0) using namespace std; const int maxn = 99991; bool hash[maxn+10]; int idx[maxn+10]; LL val[maxn+10]; LL gcd(LL a, LL b) { if(b == 0) return a; return gcd(b,a%b); } void extend_gcd(LL a, LL b, LL &x, LL &y) { if(b == 0) { x = 1; y = 0; return; } extend_gcd(b,a%b,x,y); LL t = x; x = y; y = t-a/b*y; } void insert(int id, LL vv) { LL v = vv%maxn; while(hash[v] && val[v] != vv) { v++; if(v == maxn) v -= maxn; } if(hash[v] == false) { hash[v] = true; idx[v] = id; val[v] = vv; } } int found(LL vv) { LL v = vv%maxn; while(hash[v] && val[v] != vv) { v++; if(v == maxn) v -= maxn; } if(hash[v] == false) return -1; return idx[v]; } LL baby_step(LL A, LL B, LL C) { memset(hash,false,sizeof(hash)); memset(idx,-1,sizeof(idx)); memset(val,-1,sizeof(val)); //首先特判log(C)以内的解。因为下面消因子法解出来的x >= b,但有可能x的解是小于b的。所以先特判。 LL ans = 1; for(int i = 0; i <= 50; i++) { if(ans == B) return i; ans = ans*A%C; } //消因子,直到gcd(A,C) = 1,就可以用普通的baby_step LL D = 1%C,tmp; LL b = 0; while((tmp = gcd(A,C)) != 1) { if(B%tmp) return -1; b++; B = B/tmp; C = C/tmp; D = D*A/tmp%C; } LL M = ceil(sqrt(C*1.0)); LL k = 1; for(int i = 0; i < M; i++) { insert(i,k); k = k*A%C; } LL x,y; for(int i = 0; i < M; i++) { extend_gcd(D,C,x,y); x = x*B; x = (x%C+C)%C; int jj = found(x); if(jj != -1) return (LL)i*M+(LL)jj+b; D = D*k%C; } return -1; } int main() { LL A,B,C; while(~scanf("%lld %lld %lld",&A,&C,&B)) { if(A == 0 && B == 0 && C == 0) break; LL ans = baby_step(A,B,C); if(ans == -1) printf("No Solution\n"); else printf("%lld\n",ans); } return 0; }