您的位置:首页 > 其它

hdu 1395(欧拉函数)

2016-05-26 17:27 239 查看

2^x mod n = 1

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 15810 Accepted Submission(s): 4914


[align=left]Problem Description[/align]
Give a number n, find the minimum x(x>0) that satisfies 2^x mod n = 1.

[align=left]Input[/align]
One positive integer on each line, the value of n.

[align=left]Output[/align]
If the minimum x exists, print a line with 2^x mod n = 1.

Print 2^? mod n = 1 otherwise.

You should replace x and n with specific numbers.

[align=left]Sample Input[/align]

2
5

[align=left]Sample Output[/align]

2^? mod 2 = 1 2^4 mod 5 = 1
这里提供两种方法来做,暴力或者欧拉函数。但是暴力我感觉的话数据量大一点可能就AC不了了。
暴力做法(大一的时候写的):

#include<math.h>
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int n=1000000;
int quick_pow_mod(int a,int b,int c)
{
int ans=1;
while(b>0)
{
if(b&1)
ans=(a*ans)%c;
b=b>>1;
a=(a*a)%c;
}
return ans;
}

int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int flag=1,t,k;
if(n%2==0 || n==1) printf("2^? mod %d = 1\n",n);   //n=1!!!!!!!!
else
{
for(int i=1; ; i++)
{
k=quick_pow_mod(2,i,n);
if(k==1)
{
t=i;
flag=0;
break;
}
}
if(flag)
printf("2^? mod %d = 1\n",n);
else printf("2^%d mod %d = 1\n",t,n);
}

}
}


欧拉函数:

用φ(n)表示不大于n且与n互素的数的个数,该函数以欧拉的名字命名,称为欧拉函数。

如果n是一个素数,即n = p,那么φ(n) = p-1(所有小于n的都互素);
如果n是素数的k次幂,即n = p^k,那么φ(n) = p^k - p^(k-1) (除了p的倍数其它都互素);
如果m和n互素,那么φ(mn) = φ(m)φ(n)(可以利用上面两个性质进行推导)。
将n分解成如图二-4-1的素因子形式,那么利用上面的定理可得φ(n)



欧拉定理:若n,a为正整数,且n,a互素,则:


但是我们求出的欧拉函数并不是这个方程最小的解。它的解有可能在它的因子中,这个是可以证明的。这里就不详细证明了。分解因子然后得到最小的解。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
using namespace std;
typedef long long LL;
const int N = 10000;
bool p
;
int euler
;
int e
;
void getEuler()
{
memset(euler,0,sizeof(euler));
euler[1] = 1;
for(int i = 2; i <= N; i++)
if(!euler[i])
for(int j = i; j <= N; j+= i)
{
if(!euler[j])
euler[j] = j;
euler[j] = euler[j]/i*(i-1);
}
}
int pow_mod(int a,int b,int mod)
{
int ans = 1;
while(b)
{
if(b&1) ans = ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
int main()
{
getEuler();
int n;
while(~scanf("%d",&n))
{
if(n%2&&n!=1)
{
int m = euler
;
memset(e,0,sizeof(e));
int id=0;
e[id++] = m;
for(int i=2; i*i<=m; i++) ///分解出m所有的因子
{
if(m%i==0)
{
if(i*i==m) e[id++] =i;
else
{
e[id++]=i;
e[id++]=m/i;
}
}
}
sort(e,e+id);
int ans = m;
for(int i=0; i<id; i++)
{
if(pow_mod(2,e[i],n)==1)
{
ans = e[i];
break;
}
}
printf("2^%d mod %d = 1\n",ans,n);
}
else printf("2^? mod %d = 1\n",n);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: