不理解Baby Step Giant Step算法,请戳:
http://www.cnblogs.com/chenxiwenruo/p/3554885.html
#include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #define SIZE 99991 /* POJ 3243 AC 求解同余方程: A^x=B(mod C) */ using namespace std; struct HashTable{ int key[SIZE]; //对应A^i int val[SIZE]; //对应i void init(){ memset(key,-1,sizeof(key)); memset(val,-1,sizeof(val)); } int hfind(int k){ int kk=k%SIZE; while(key[kk]!=k && key[kk]!=-1){ kk=(kk+1)%SIZE; //原先写成了kk=(kk+1)&SIZE;导致一直TLE。。。 } return val[kk]; } void hinsert(int v,int k){ int kk=k%SIZE; while(key[kk]!=-1 && key[kk]!=k){ kk=(kk+1)%SIZE; } if(key[kk]==-1){ key[kk]=k; val[kk]=v; } } }h; int gcd(int a,int b){ return b==0?a:gcd(b,a%b); } int exgcd(int a,int b,int &x,int &y){ if(b==0){ x=1; y=0; return a; } int d=exgcd(b,a%b,x,y); int tmp=x; x=y; y=tmp-a/b*y; return d; } //求解ax=b(mod c) int solvex(int a,int b,int c){ int x,y; exgcd(a,c,x,y); x=((long long)x*b%c+c)%c; //注意这里要强制转换成long long,不然x*b会超出int范围 return x; } long long quickPow(long long a,int b,int mod){ long long ret=1%mod; a=a%mod; while(b){ if(b&1) ret=(ret*a)%mod; a=(a*a)%mod; b=b>>1; } return ret; } int BabyStep(int A,int B,int C){ B=B%C; //注意这里先要将B对C取模 h.init(); int d=0; long long D=1%C,buf=D; for(int i=0;i<=100;buf=buf*A%C,++i){ if(buf==B) return i; } int tmp; while((tmp=gcd(A,C))!=1){ if(B%tmp) return -1; d++; B=B/tmp; C=C/tmp; D=D*A/tmp%C; } int m=(int)ceil(sqrt((double)C)); buf=1%C; for(int i=0;i<m;buf=buf*A%C,++i){ h.hinsert(i,(int)buf); } long long K=quickPow((long long)A,m,C); for(int i=0;i<m;D=D*K%C,++i){ int ans=solvex((int)D,B,C); int j=h.hfind(ans); if(j!=-1) return i*m+j+d; } return -1; } int main() { int A,B,C; while(scanf("%d%d%d",&A,&C,&B)!=EOF){ if(A==0 && B==0 && C==0) break; int ans=BabyStep(A,B,C); if(ans==-1) printf("No Solution\n"); else printf("%d\n",ans); } return 0; }
该题和POJ 2417 一样,代码稍微改改就能AC。
POJ 3243 Clever Y (求解高次同余方程A^x=B(mod C) Baby Step Giant Step算法)
原文:http://www.cnblogs.com/chenxiwenruo/p/3554894.html