您的位置:首页 > 其它

HDU 1395 2^x mod n = 1

2014-05-11 10:33 218 查看
链接: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;
}


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM 数学