exBSGS學習筆記
阿新 • • 發佈:2019-05-17
tps clear show isp std else count lld stk
前置知識
大步小步定理
以及是個人都會的exgcd
Problem
洛谷P4195 【模板】exBSGS/Spoj3105 Mod
Solution
\[ a^x\equiv b\mod p\a\times a^{x-1}\equiv b\mod p\令X=a^{x-1}\\therefore a·X+p·Y=b\exgcd求出X\令d=gcd(a,p)\\frac ad*X\equiv \frac bd\mod \frac pd\X\equiv\frac bd*\frac da\mod \frac pd\a^{x-1}\equiv\frac ba\mod \frac pd\\]
Code
#include<bits/stdc++.h> #define int long long using namespace std; struct Hashmap{ static const int MAXINT=((1<<30)-1)*2+1,Ha=999917,maxe=46340; int E,lnk[Ha],son[maxe+5],nxt[maxe+5],w[maxe+5]; int top,stk[maxe+5]; void clear(){ E=0; while(top) lnk[stk[top--]]=0; } void Add(int x,int y){ son[++E]=y; nxt[E]=lnk[x]; w[E]=MAXINT; lnk[x]=E; } bool count(int y){ int x=y%Ha; for(int j=lnk[x];j;j=nxt[j]) if(y==son[j])return true; return false; } int& operator[](int y){ int x=y%Ha; for(int j=lnk[x];j;j=nxt[j]) if(y==son[j])return w[j]; Add(x,y); stk[++top]=x; return w[E]; } }hs; int gcd(int a,int b){return b?gcd(b,a%b):a;} int exgcd(int a,int b,int &x,int &y){ if(!b){return x=1,y=0,a;} int re=exgcd(b,a%b,x,y),t=x; x=y;y=t-a/b*y; return re; } int fk(int a,int b,int p){ if(p==1)return 0; if(b==1)return a?0:-1; if(a%p==0)return b?-1:1; int Gcd,d=1,add=0; while((Gcd=gcd(a,p))>1){ if(b%Gcd)return -1; b/=Gcd,p/=Gcd,d=(d*a/Gcd)%p; add++; } for(int i=0,fkk=1;i<add;i++,fkk=(fkk*a)%p) if(fkk==b)return i; int m=sqrt(p),bs=1;hs.clear(); for(int i=0;i<m;i++){ hs[bs]=min(hs[bs],i); bs=(bs*a)%p; } for(int i=0;i<m;i++){ int x,y; Gcd=exgcd(d,p,x,y); x=(x*b%p+p)%p; if(hs.count(x))return i*m+hs[x]+add; d=(d*bs)%p; } return -1; } signed main(){ int a,b,p,ans; while(1){ scanf("%lld%lld%lld",&a,&p,&b); if(p==0)break; ans=fk(a,b,p); if(ans==-1)puts("No Solution"); else printf("%lld\n",ans); } return 0; } /* 5 58 33 2 4 3 2 5 1 2 5 2 2 5 3 2 5 4 3 5 1 3 5 2 3 5 3 3 5 4 4 5 1 4 5 2 4 5 3 4 5 4 2 12345701 1111111 65537 1111111121 1111111111 0 0 0 */
exBSGS學習筆記