#include <cstdio> #include <cstring> #include <cmath> #include <map> #include <iostream> #include <algorithm> using namespace std; #define LL long long //快速幂求a^b LL pow_mod(LL a,LL b,LL n) { LL s=1; while(b) { if(b&1) s=(s*a)%n; a=(a*a)%n; b=b>>1; } return s; } //求解模方程a^x=b(mod n)。n为素数,无解返回-1 //费马小定理a^(n-1)=1(mod n),n为素数。a^0=1,所以循环节小于等于n,即如果存在解,则最小解x<=n LL log_mod (LL a,LL b,LL n) { LL m,v,e=1,i; m=ceil(sqrt(n+0.5)); //x=i*m+j //v=inv(pow_mod(a,m,n),n); //a^m*v=1(mod n) v=pow_mod(a,n-m-1,n); map<LL,LL>x; x[1]=m; for(i=1;i<m;i++) //建哈希表,保存x^0,x^1,...,x^m-1 { e=(e*a)%n; if(!x[e])x[e]=i; } for(i=0;i<m;i++)//每次增加m次方,遍历所有1<=x<=n { if(x[b]) { LL num=x[b]; x.clear();//需要清空,不然会爆内存 return i*m+(num==m?0:num); } b=(b*v)%n; //b=b/(a^m) } return -1; } int main() { LL a,b,n; while(scanf("%I64d%I64d%I64d",&n,&a,&b)!=EOF) { LL ans=log_mod(a,b,n); if(ans==-1)printf("no solution\n"); else printf("%I64d\n",ans); } return 0; } /* 求解模方程a^x=b(mod n),n为素数。 模板题。 时间复杂度O(sqrt(n)*logn) */