BZOJ2480 Spoj3105 Mod 数论 扩展BSGS
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2480.html
题目传送门 - BZOJ2480
题意
已知数 $a,p,b$ ,求满足 $a^x≡b \pmod p $ 的最小自然数 $x$ 。
$a,p,b\leq 10^9$
题解
ExBSGS模板题。
UPD(2018-09-10):
详见数论总结。
传送门 - https://www.cnblogs.com/zhouzhendong/p/Number-theory-Residue-System.html
代码
#include <bits/stdc++.h> using namespace std; int a,p,b; int Pow(int x,int y,int mod){ int ans=1; for (;y;y>>=1,x=1LL*x*x%mod) if (y&1) ans=1LL*ans*x%mod; return ans; } int gcd(int x,int y){ return y?gcd(y,x%y):x; } struct hash_map{ static const int Ti=233,mod=1<<16; int cnt,k[mod+1],v[mod+1],nxt[mod+1],fst[mod+1]; int Hash(int x){ int v=x&(mod-1); return v==0?mod:v; } void clear(){ cnt=0; memset(fst,0,sizeof fst); } void update(int x,int a){ int y=Hash(x); for (int p=fst[y];p;p=nxt[p]) if (k[p]==x){ v[p]=a; return; } k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt,v[cnt]=a; return; } int find(int x){ int y=Hash(x); for (int p=fst[y];p;p=nxt[p]) if (k[p]==x) return v[p]; return 0; } int &operator [] (int x){ int y=Hash(x); for (int p=fst[y];p;p=nxt[p]) if (k[p]==x) return v[p]; k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt; return v[cnt]=0; } }Map; int ExBSGS(int A,int B,int P){ A%=P,B%=P; int k=0,v=1; while (1){ int g=gcd(A,P); if (g==1) break; if (B%g) return -1; k++,B/=g,P/=g,v=1LL*v*(A/g)%P; if (v==B) return k; } if (P==1) return k; int M=max((int)sqrt(1.0*P),1),AM=Pow(A,M,P); Map.clear(); for (int b=0,pw=B;b<M;b+=1,pw=1LL*pw*A%P) Map.update(pw,b+1); for (int a=M,pw=1LL*v*AM%P;a-M<P;a+=M,pw=1LL*pw*AM%P){ int v=Map.find(pw); if (v) return a-(v-1)+k; } return -1; } int main(){ while (~scanf("%d%d%d",&a,&p,&b)&&(a||b||p)){ int ans=ExBSGS(a,b,p); if (~ans) printf("%d\n",ans); else puts("No Solution"); } return 0; }