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 }
View Code

 

 

posted @ 2018-06-22 12:12  鲸头鹳  阅读(97)  评论(0编辑  收藏  举报