链接:http://acm.hdu.edu.cn/showproblem.php?pid=1395
欧拉定理 如果gcd(a,m)==1,a^(euler_phi(n))≡1(mod n)。
euler_phi(n)为欧拉函数,其作用是返回与小于n且与n互质的数的个数...令m=euler_phi(n),必有(a^m)%n==1,,但m不一定是最小的..
当输入的数为偶数,或为1时,x不存在。
(a*b)%M=a%M*b%M
下面是个暴力的方法:
#include <iostream> using namespace std; int main() { int n; int s; int ans; while(scanf("%d",&n)!=EOF) { s=2; ans=1; if(n%2==0||n==1) printf("2^? mod %d = 1 ",n); else { while(1) { s*=2; ans++; if(s%n==1) break; if(s>n) //防止溢出 s%=n; } printf("2^%d mod %d = 1 ",ans,n); } } return 0; }
下面再贴一个求幂求模的函数:
__int64 qpow(int a,int b,int r) //二分求幂,计算a^b%r { if(b==0) return 1; if(b==1) return a%r; __int64 ans=qpow(a,b/2,r); ans=(ans*ans)%r; if(b%2) ans=(a*ans)%r; return ans; }
下面用欧拉函数,搜索m的因子即可:
#include <iostream> using namespace std; int main() { __int64 qpow(int a,int b,int r) ; __int64 Eular(__int64 n); int n; int s; int i; int m; while(scanf("%d",&n)!=EOF) { s=2; if(n%2==0||n==1) printf("2^? mod %d = 1 ",n); else { m=Eular(n); for (i=1;;i++) { if(m%i==0&&qpow(2,i,n)==1) break; } printf("2^%d mod %d = 1 ",i,n); } } return 0; } __int64 qpow(int a,int b,int r) //二分求幂,计算a^b%r { if(b==0) return 1; if(b==1) return a%r; __int64 ans=qpow(a,b/2,r); ans=(ans*ans)%r; if(b%2) ans=(a*ans)%r; return ans; } __int64 Eular(__int64 n) //欧拉函数 { __int64 ret=n; for(int i=2;i*i<=n;i++) if(n%i==0) { ret-=ret/i; while(n%i==0)n/=i; if(n==1)break; } if(n!=1)ret-=ret/n; return ret; }