【文文殿下】ExBSGS
阿新 • • 發佈:2019-01-04
無需逆元版本:
#include<cstdio> #include<cassert> #include<cmath> #include<map> typedef long long ll; ll gcd(ll a,ll b) { return b?gcd(b,a%b):a; } ll qpow(ll a,ll b,ll p) { ll ret = 1; while(b) { if(b&1) { ret=ret*a%p; } a=a*a%p; b>>=1; } return ret; } ll exgcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1;y=0; return a; } ll d = exgcd(b,a%b,x,y); ll tmp = x; x = y; y=tmp-a/b*y; return d; } inline ll bsgs(ll a,ll b,ll p) { std::map<ll,ll> M; if(p==1) return 0; a%=p;b%=p; ll d,cnt=0,q=1; while((d=gcd(a,p))!=1) { if(b==1) return cnt; if(b%d) return -1; b/=d; p/=d; ++cnt; q=a/d*q%p; } ll lmt = ceil(sqrt(p)); ll tmp = b%p; for(int i = 0;i<lmt;++i,tmp=tmp*a%p) { M[tmp]=i; } tmp = qpow(a,lmt,p); for(int i = 1;i<=lmt+1;++i) { q=q*tmp%p; if(M.count(q)) { return i*lmt-M[q]+cnt; } } return -1; } int main() { ll a,b,p; scanf("%lld%lld%lld",&a,&p,&b); while(a||b||p) { ll ans = bsgs(a,b,p); if(ans==-1) puts("No Solution"); else printf("%lld\n",ans); scanf("%lld%lld%lld",&a,&p,&b); } return 0; }