介绍
求(1,m)区间内与m互质的数的个数
公式
其中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次幂, ,因为除了p的倍数外,其他数都跟n互质。
变式二:
欧拉函数是积性函数——若m,n互质,
特殊性质:当n为奇数时, , 证明与上述类似。
若n为质数则
代码实现
求单个欧拉函数
#include <iostream>
using namespace std;
int Euler(int n)
{
int res = n , a = n;
for(int i = 2 ; i*i <= a ; i++)
{
if(a % i == 0) //i一定是素数
{
res = res / i * (i - 1); //根据公式
while(a % i == 0) //把相同的除数排除
{
a /= i;
}
}
}
if(a > 1) //最后只剩下 小于4的素数 或者n本身就是素数
res = res / a *(a - 1);
return res;
}
int main()
{
int n;
while(cin >> n)
{
cout << Euler(n) << endl;
}
}
线性筛求1-N的所有欧拉函数
//离线打表
//筛选法求欧拉函数,时间复杂度O(nloglogn)
//跟埃式筛法求素数差不多
#include <iostream>
using namespace std;
const int MAXN = 100010;
int a[MAXN];
void init()
{
for(int i = 1 ; i <= MAXN ; i++)
a[i] = i;
a[1] = 0;
for(int i = 1 ; i <= MAXN ; i++)
{
if(a[i] == i)
{
for(int j = i ; j <= MAXN ; j += i)
a[j] = a[j] / i * (i - 1);
}
}
}
int main()
{
init();
int n;
while(cin >> n)
{
cout << a[n] << endl;
}
}