上一篇博文中说道了baby step giant step的方法(简称BSGS),不过对于XY mod Z = K ,若x和z并不互质,则不能直接套用BSGS的方法了。

  为什么?因为这时候不存在逆元了啊,那么怎么办呢?

  既然是x和z不互质,那么我们就想办法让他们互质,再套用BSGS的解法即可。(这就是所谓的消因子法)

 

 

          【POJ3243】拓展BSGS(附hash版)

 

 

代码如下:

  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 }
poj3243 (二分版)

相关文章:

  • 2022-03-07
  • 2021-08-30
  • 2022-12-23
  • 2021-08-28
  • 2022-12-23
  • 2022-12-23
  • 2022-02-22
  • 2021-10-31
猜你喜欢
  • 2022-12-23
  • 2022-02-21
  • 2021-06-18
  • 2021-10-29
  • 2021-06-11
  • 2022-12-23
  • 2021-07-14
相关资源
相似解决方案