上一篇博文中说道了baby step giant step的方法(简称BSGS),不过对于XY mod Z = K ,若x和z并不互质,则不能直接套用BSGS的方法了。
为什么?因为这时候不存在逆元了啊,那么怎么办呢?
既然是x和z不互质,那么我们就想办法让他们互质,再套用BSGS的解法即可。(这就是所谓的消因子法)
代码如下:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<cmath> 7 using namespace std; 8 #define LL long long 9 #define Maxn 40000 10 11 LL x,z,k,aa,m; 12 int cnt,num; 13 int ok; 14 15 struct node 16 { 17 int idx;LL val; 18 }baby[Maxn]; 19 20 LL ax,ay; 21 LL exgcd(LL a,LL b) 22 { 23 if(b==0) {ax=1,ay=0;return a;} 24 LL g=exgcd(b,a%b); 25 LL yy=ay; 26 ay=ax-a/b*ay;ax=yy; 27 return g; 28 } 29 30 bool cmp(node x,node y) {return x.val==y.val?x.idx<y.idx:x.val<y.val;} 31 32 int ffind(LL x) 33 { 34 int head=0,tail=cnt; 35 while(head<tail) 36 { 37 int mid=(head+tail)>>1; 38 if(baby[mid].val==x) return baby[mid].idx; 39 if(baby[mid].val>x) tail=mid-1; 40 else head=mid+1; 41 } 42 if(baby[head].val==x) return baby[head].idx; 43 return -1; 44 } 45 46 bool init() 47 { 48 scanf("%lld%lld%lld",&x,&z,&k); 49 //if(==EOF) return 0; 50 if(x==0&&z==0&&k==0) return 0;k%=z; 51 LL g,bm; 52 bm=1%z;aa=1,num=0;ok=1; 53 //if(k>=z) {ok=0;return 1;} 54 for(int i=0;i<=100;i++) if(bm==k) {printf("%d\n",i);ok=0;return 1;} 55 else bm=(bm*x)%z; 56 while((g=exgcd(x,z))!=1) 57 { 58 aa=(aa*x/g)%z,z/=g;num++; 59 if(k%g!=0) {ok=-1;break;} 60 k/=g; 61 } 62 return 1; 63 } 64 65 LL BSGS() 66 { 67 baby[0].idx=0,baby[0].val=aa%z; 68 m=(LL)(ceil(double(sqrt((double)z)))); 69 for(int i=1;i<=m;i++) baby[i].idx=i,baby[i].val=(baby[i-1].val*x)%z; 70 LL bm=1%z,ans=-1,g; 71 for(int i=1;i<=m;i++) bm=(bm*x)%z; 72 g=exgcd(bm,z); 73 bm=ax/g; bm=(bm%(z/g)+(z/g))%(z/g); 74 if(bm==0) bm=z/g; 75 sort(baby,baby+m+1,cmp);cnt=0; 76 for(int i=1;i<=m;i++) if(baby[i].val!=baby[cnt].val) baby[++cnt]=baby[i]; 77 LL tmp=k; 78 for(int i=0;i<=m;i++) 79 { 80 int j; 81 if((j=ffind(tmp))!=-1) 82 { 83 ans=i*m+j; 84 break; 85 } 86 tmp=(tmp*bm)%z; 87 } 88 return ans; 89 } 90 91 int main() 92 { 93 while(1) 94 { 95 LL ans; 96 if(!init()) break; 97 if(ok==0) continue; 98 else if(ok==-1) printf("No Solution\n"); 99 else 100 { 101 ans=BSGS(); 102 if(ans==-1) printf("No Solution\n"); 103 else printf("%lld\n",ans+num); 104 } 105 } 106 return 0; 107 }