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 }