刚开始花了很长时间化简,求出x^k mod a0=1来却不知道怎么去求解。。。。
看了解题报告,套用欧拉函数,因为 x^φ(a0) mod a0 =1,所以除了无解的情况,最大的解也不会超过φ(a0),然后比较φ(a0)的因子里,找一个最小的即可。
对于无解的情况,即 Gcd(x,a0)!=1 ,假设存在共同因子m,那么x=x' * m,a0=a0' * m;则 (x' * m)^k - t* (a0' * m) =1 ,化简 m*( x'^k * m^(k-1) - t*a0' )=1,显然,对于m大于1是无解的
code:
#include <cstdio> #include <cstring> #include <algorithm> #define LL __int64 using namespace std; const int MAXN = 11; int n; LL Gcd(LL a, LL b) { return b==0?a:Gcd(b,a%b); } LL PowMod(LL n,LL exp,LL mod) { LL ret=1,tmp=n%mod; while(exp) { if(exp&1) ret=ret*tmp%mod; exp>>=1; tmp=tmp*tmp%mod; } return ret; } LL Eular(LL n) { LL fac,ans=1; for(fac=2;fac*fac<=n;fac++) { if(n%fac==0) { n/=fac; ans*=fac-1; while(n%fac==0) { n/=fac; ans*=fac; } } } if(n>1) ans*=n-1; return ans; } LL solve(LL x,LL y,LL a0) { if(y==0) return 1; LL gcd=Gcd(y/(x-1),a0); a0/=gcd; if(Gcd(a0,x)!=1) return -1; LL lim=Eular(a0); LL minn=lim; for(LL fac=2;fac*fac<=lim;fac++) { if(lim%fac==0) { if(PowMod(x,fac,a0)==1&&fac<minn) minn=fac; if(PowMod(x,lim/fac,a0)==1&&fac<minn) minn=lim/fac; } } return minn; } int main() { LL x,y,a0,ans; while(~scanf("%I64d%I64d%I64d",&x,&y,&a0)) { ans=solve(x,y,a0); if(ans==-1) puts("Impossible!"); else printf("%I64d\n",ans); } return 0; }