题目大概是小于n的数中有多少个与n互素的数。这里可以用欧拉公式。
下面简要介绍下欧拉函数。(转自百度百科)
简介编辑
φ函数的值 通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。φ(1)=1(唯一和1
互质的数(小于等于1)就是1本身)。 (注意:每种质因数只一个。比如12=2*2*3那么φ(12)=12*(1-1/2)*(1-1/3)=4
若n是质数p的k次幂,φ(n)=p^k-p^(k-1)=(p-1)p^(k-1),因为除了p的倍数外,其他数都跟n互质。
设n为正整数,以 φ(n)表示不超过n且与n互
素的正整数的个数,称为n的欧拉函数值,这里函数
φ:N→N,n→φ(n)称为欧拉函数。
欧拉函数是
积性函数——若m,n互质,φ(mn)=φ(m)φ(n)。
特殊性质:当n为奇数时,φ(2n)=φ(n), 证明与上述类似。
2证明编辑
若
n= ∏p^(α(下标p))
p|n
则φ(n)=∏(p-1)p^(α(下标p)-1)=n∏(1-1/p)
p|n p|n
例如φ(72)=φ(2^3×3^2)=(2-1)2^(3-1)×(3-1)3^(2-1)=24
与欧拉定理、
费马小定理的关系
对任何两个互质的正整数a, m, m>=2有
a^φ(m)≡1(mod m)
即欧拉定理
当m是质数p时,此式则为:
a^(p-1)≡1(mod m)
即费马小定理。
#include <iostream>
#include<cmath>
using namespace std;
int prime(int n)//判断素数
{
int k=sqrt(n),i;
for(i=2;i<=k;i++)
{
if(n%i==0)
break;
}
if(i<=k)
return 0;
else
return 1;
}
int count1(int m)
{
int i,k=0,s=1,a[100],j;
if(prime(m)||(m==1))//特殊情况处理
return m-1;
for(i=2;i<m;i++)
{
if(m%i==0&&prime(i))//找素因子
{
a[k]=i;
k++;
}
}
s=(m/a[0])*(a[0]-1);
for(j=1;j<k;j++)//套公式
{
s=(s/a[j])*(a[j]-1);
}
return s;
}
int main()
{
int n,m,i;
while(cin>>n)
{
for(i=0;i<n;i++)
{
cin>>m;
cout<<count1(m)<<endl;
}
}
return 0;
}
注:此题比较简单,出问题的原因应该是不知道公式或者没有注意到特殊情况。