BSGS(Baby-Step-Giant-Step)算法及其應用
阿新 • • 發佈:2018-08-17
stat namespace ret baby .com min struct base while
先來稍微回顧一下,我們已經會求模線性方程(包括其特殊情況乘法逆元)
我們還會進行冪取模的快速算法(模是質數用費馬小定理,模一般情況用歐拉定理)
對於冪中指數特別大的情況,我們還延伸出了拓展歐拉定理來解決
對於模線性方程組來說,模數互質的時候直接用孫子定理
模數不互質的時候用方程合並的思想,引申出拓展中國剩余定理
接下來要學的這個東西可以說也是解模方程的,只不過是超越方程
咋超越的呢?
方法不容變通,直接抄過來
轉自https://blog.csdn.net/zzkksunboy/article/details/73162229
典型例題是POJ2417,就是求這個東西
要求一個最小整數解
腦子不夠用了QAQ睡眠QAQ
1 #include<cmath> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 struct Hashmap 6 { 7 static const int Ha=999917,maxe=46340; 8 int E,lnk[Ha],son[maxe+5],nxt[maxe+5],w[maxe+5]; 9 int top,stk[maxe+5]; 10 void clear(){E=0;while(top) lnk[stk[top--]]=0;} 11 void Add(int x,int y){son[++E]=y;nxt[E]=lnk[x];w[E]=0x7fffffff;lnk[x]=E;} 12 bool count(int y) 13 { 14 int x=y%Ha; 15 for(int j=lnk[x];j;j=nxt[j]) 16 if(y==son[j]) return true; 17 return false; 18 } 19 int& operator [](int y) 20 { 21int x=y%Ha; 22 for(int j=lnk[x];j;j=nxt[j]) 23 if(y==son[j]) return w[j]; 24 Add(x,y);stk[++top]=x;return w[E]; 25 } 26 }f; 27 int exgcd(int a,int b,int &x,int &y) 28 { 29 if(b==0) {x=1;y=0;return a;} 30 int r=exgcd(b,a%b,x,y); 31 int t=x;x=y;y=t-a/b*y; 32 return r; 33 } 34 int BSGS(int A,int B,int C) 35 { 36 if(C==1) if(B==0) return A!=1;else return -1; 37 if(B==1) if(A!=0) return 0;else return -1; 38 if(A%C==0) if(B==0) return 1;else return -1; 39 int m=ceil(sqrt(C)),D=1,Base=1;f.clear(); 40 for(int i=0;i<=m-1;i++) 41 { 42 f[Base]=min(f[Base],i); 43 Base=((long long)Base*A)%C; 44 } 45 for(int i=0;i<=m-1;i++) 46 { 47 int x,y,r=exgcd(D,C,x,y); 48 x=((long long)x*B%C+C)%C; 49 if(f.count(x)) return i*m+f[x]; 50 D=((long long)D*Base)%C; 51 } 52 return -1; 53 } 54 int main() 55 { 56 int A,B,C; 57 while(scanf("%d%d%d",&C,&A,&B)==3) 58 { 59 int ans=BSGS(A,B,C); 60 if(ans==-1) printf("no solution\n"); 61 else printf("%d\n",ans); 62 } 63 return 0; 64 }
BSGS(Baby-Step-Giant-Step)算法及其應用