POJ 3243 Clever Y 扩展BSGS

http://poj.org/problem?id=3243

这道题的输入数据输入后需要将a和b都%p

https://blog.csdn.net/zzkksunboy/article/details/73162229

在大约sqrt( p )的复杂度求出 ( a^x ) % p = b % p中的x

扩展bsgs增加了对p不是素数的情况的处理。

扩展bsgs在处理过a,b,p之后进行bsgs的时候x处理不到num以下的部分,这部分在处理a,b,p的时候处理过了(b=1输出num)所以不用考虑。

所以实际上扩展bsgs和普通bsgs只多了一个处理的循环部分。

ac一次之后我又把多余的(非预处理循环内的)判定a==b和b==1的情况的部分删除了,也是对的,最开始在这些没必要的部分上纠结真是画蛇添足了。

 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 LL mgcd(LL x,LL y){return y==0?x:mgcd(y,x%y);}
12 int main(){
13     while(~scanf("%lld%lld%lld",&a,&p,&b)){
14         if(a==0&&p==0&&b==0)break;b=b%p;a=a%p;
15         LL x=1,y=1,t=0,d=mgcd(a,p),ff=0;
16         while(d!=1){
17             if(b==1){printf("%lld\n",t);ff=1;break;}
18             if(b%d!=0){printf("No Solution\n");ff=1;break;}
19             ++t;a/=d;b/=d;p/=d;
20             y=(y*a)%p;a=a*d;
21             d=mgcd(a,p);
22         }if(ff)continue;
23         a%=p;b%=p;
24         LL w=(LL)sqrt((double)p);if(w*w!=p)++w;
25         q[b]=-1; for(int i=1;i<=w;++i){x=(x*a)%p;LL z=(b*x)%p;q[z]=i;}
26         bool f=0;LL m=10000000000000000LL;
27         for(int i=1;i<=w;++i){
28             y=(y*x)%p;
29             if(q[y]!=0){
30                 LL z=q[y];if(z==-1) z=0;
31                 z=(LL)i*w-z;f=1;
32                 m=min(z+t,m);
33             }
34         }
35         q[b]=0;x=1;
36         for(int i=1;i<=w;++i){x=(x*a)%p;LL z=(b*x)%p;q[z]=0;}
37         if(!f)printf("No Solution\n");
38         else printf("%lld\n",m);
39     }
40     return 0;
41 }
View Code

 

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