EXBSGS模板
我之前把有一处b和c弄反了,有点困...然后调了半天
(exbsgs比excrt简单多了)
求x的最小正整数解
原式子拆成
在bsgs中,保证a,b互质,这样求出的逆元挪过去才对
但exbsgs中并不保证,所以必须不断取gcd(a,b)保证a,c互质
令n为不断求gcd的总次数
接下来式子变成了这样
由于左边肯定和c互质,所以那部分直接挪右面求逆元再更新一下答案就行了
剩下的按BSGS思想移项,得
然后每次预处理存进hash表/map,再在哈希表里找是否存在某一个值等于
,找到了说明成立
1 struct Hsh{ 2 #define maxn 400000 3 int head[N1],to[M1],nxt[M1],val[M1],cte; 4 void ins(int x,int w) 5 { 6 int u=x%maxn,j,v; 7 for(j=head[u];j;j=nxt[j]) 8 { 9 v=to[j]; 10 if(v==x) return; 11 } 12 cte++; to[cte]=x; nxt[cte]=head[u]; 13 head[u]=cte; val[cte]=w; 14 } 15 int find(int x) 16 { 17 int u=x%maxn,j,v; 18 for(j=head[u];j;j=nxt[j]) 19 { 20 v=to[j]; 21 if(v==x) return val[j]; 22 } 23 return -1; 24 } 25 #undef maxn 26 }h; 27 28 int que[100],tl; 29 int solve() 30 { 31 int g,i,sq;ll pw,ans=inf,now,tmp; 32 if(A%B==0) return -1; 33 A%=B; C%=B; tl=0; 34 while(1) 35 { 36 g=gcd(A,B); 37 if(g==1) break; 38 if(C%g!=0) return -1; 39 B/=g,C/=g; que[++tl]=A/g; 40 } 41 ll inv,invy; 42 for(i=1;i<=tl;i++) 43 { 44 exgcd(que[i],B,inv,invy); inv=(inv%B+B)%B; 45 C=inv*C%B; 46 } 47 if(C==1) return tl; 48 sq=sqrt(B); 49 for(pw=qpow(A,sq,B),now=1,i=1;(i-1)*sq<B;i++) 50 { 51 now=now*pw%B; 52 h.ins(now,i); 53 } 54 for(now=C,i=0;i<sq;i++) 55 { 56 tmp=h.find(now); 57 if(tmp!=-1) ans=min(ans,tmp*sq-i); 58 now=now*A%B; 59 } 60 memset(&h,0,sizeof(h)); 61 if(ans==inf) return -1; 62 return ans+tl; 63 } 64 65 int main() 66 { 67 int ans; 68 while(scanf("%d%d%d",&A,&B,&C)&&A!=0){ 69 ans=solve(); 70 if(ans==-1) puts("No Solution"); 71 else printf("%d ",ans); 72 } 73 return 0; 74 }