离散对数
#include<bits/stdc++.h> #define ll long long using namespace std; //返回a*b%n,要求0<=a,b<n ll mul_mod(ll a,ll b,ll n){ return a*b%n; } //返回a^p%n,要求0<=a<n ll pow_mod(ll a,ll p,ll n) { ll ans=1; while(p>0){ if(p&1) ans=(ans*a)%n; a=(a*a)%n; p>>=1; } return ans; } //扩展欧几里得算法 void gcd(ll a,ll b,ll &d,ll &x,ll &y) { if(!b){ d=a; x=1,y=0; } else{ gcd(b,a%b,d,y,x); y-=(a/b)*x; } } //计算模n下a的逆,如果不存在逆,返回-1 ll inv(ll a,ll n) { ll d,x,y; gcd(a,n,d,x,y); return d==1?(x+n)%n:-1; } //求解模方程a^x=b(mod n)n为素数。无解返回-1 ll log_mod(ll a,ll b,ll n) { ll e=1; ll m=(ll)sqrt(n+0.5); ll v=inv(pow_mod(a,m,n),n); map<ll,ll> x; x[1]=0; for(ll i=1;i<m;i++){ e=mul_mod(e,a,n); if(!x.count(e)) x[e]=i; } for(ll i=0;i<m;i++){ if(x.count(b)) return i*m+x[b]; b=mul_mod(b,v,n); } return -1; } int main() { ll a,b,n; scanf("%lld%lld%lld",&a,&b,&n); printf("%lld",log_mod(a,b,n)); }