POJ 2417 Discrete Logging BSGS
http://poj.org/problem?id=2417
BSGS 大步小步法( baby step giant step )
sqrt( p )的复杂度求出 ( a^x ) % p = b % p中的x
https://www.cnblogs.com/mjtcn/p/6879074.html
我的代码中预处理a==b和b==1的部分其实是不必要的,因为w=sqrt(p)(向上取整),大步小步法所找的x包含从0到w^2。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<map> 7 using namespace std; 8 #define LL long long 9 LL p,a,b; 10 map<LL,LL>q; 11 int main(){ 12 while(~scanf("%lld%lld%lld",&p,&a,&b)){ 13 if(b==1){printf("0\n");continue;} 14 if(a==b){printf("1\n");continue;} 15 LL w=(LL)sqrt((double)p),x=1,y=1;if(w*w!=p)++w; 16 q[b]=-1; 17 for(int i=1;i<=w;++i){x=(x*a)%p;LL z=(b*x)%p;if(q[z]==0)q[z]=i;} 18 bool f=0; 19 for(int i=1;i<=w;++i){ 20 y=(y*x)%p; 21 if(q[y]!=0){ 22 LL z=q[y];if(z==-1) z=0; 23 z=(LL)i*w-z;f=1; 24 printf("%lld\n",z); 25 break; 26 } 27 } 28 q[b]=0;x=1; 29 for(int i=1;i<=w;++i){x=(x*a)%p;LL z=(b*x)%p;q[z]=0;} 30 if(!f)printf("no solution\n"); 31 } 32 return 0; 33 }