HDU 1395 2^x mod n = 1

链接: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",n);
		else
		{
			while(1)
			{
				s*=2;
				ans++;
				if(s%n==1)
					break;
				if(s>n)			//防止溢出
					s%=n;

			}
			printf("2^%d mod %d = 1\n",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",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\n",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;
}


 


 

你可能感兴趣的:(HDU)