本节是数论中的重要内容,也是算法竞赛中的常考点,初学者理解起来可能有些困难,需要多多体会
给定一个正整数 n,求 1∼n 中每个数的欧拉函数之和。
欧拉函数的定义:1~n中与n互质的数的个数被称为欧拉函数,记作φ(n)
欧拉函数的性质:
1.若p是质数,则φ(p) = p-1
2.若p是质数,则φ(p^k) = (k-1)*p^(k-1)
3.欧拉函数是积性函数 ,若 gcd(m,n) = 1,则有φ(m,n) = φ(m)*φ(n)
第一个性质很好证明
第二个证明如下:
已知p^k一定可以整除 p,p^2,p^3......p^k-1
那么我们可以得出,在p^k-1与p^k之间,不可能存在别的数能整除p (p是质数)
在一个循环节中,我们可以知道共有(p-1)个数是与p互质的,那么个数是(p-1)
并且循环节一共有p^k-1个,所以定理二成立
定理三的证明读者可自行查阅资料(本觏婼不会)
欧拉函数的计算公式:
由唯一分解性定理可知,n = p1^a1*p2^a2......pk^ak
则φ(n) = φ(pi^ai)
= (pi-1)*p^(ai-1)
= p^ai*
(1-(1/pi))
= n*(1-(1/pi))
所以φ(n) = n*((p1-1)/p1)*((p2-1)/p2).....
欧拉函数仅与n和其只因子有关,与次数无关
这时我们可以根据定义,用试除法来求欧拉函数
int phi(int n) // 用试除法求欧拉函数
{
int res = n;
for(int i=2;i<=n/i;i++)
{
if(n%i==0)
{
res = res*(i-1)/i;
while(n%i==0) n /= i;
}
}
if(n>0) res = res*(n-1)/n;
return res;
}
此算法的复杂度较高,有局限性,我们考虑优化
使用线性筛法求欧拉函数
在线性筛法中,每个合数m都是被其最小的只因子筛掉的
我们从小到大枚举i,并且满足不超过n
若i可以整除pj(最小只因子),那么i包含了m的所有只因子 φ(m) = pj*φ(i)
否则的话i与pj 是互质的 φ(m) = φ(pj)*φ(i) = (pj-1)*(φ(i))
const int N = 100010;
int p[N],cnt; // p数组是存储只因子个数,cnt记录数量
int phi[N]; // phi 是欧拉函数
bool vis[N]; // 标记应该去掉的合数
void get_phi(int n) // 线性筛法求欧拉函数
{
phi[1] = 1;
for(int i=2;i<=n;i++)
{
if(!vis[i]) // 没有划掉的话证明i是质数
{
p[cnt++] = i; // 将这个最小只因子存储下来
phi[i] = i-1; // 定理一
}
for(int j=0;i*p[j]<=n;j++)
{
// 这里的步骤已经给出证明
int m = i*p[j];
vis[m] = false;
if(i%p[j]==0)
{
phi[m] = phi[i]*p[j];
break;
}
else phi[m] = phi[i]*(p[j]-1);
}
}
}
下面的话给出本题的完整代码:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1000010;
typedef long long LL;
int p[N],cnt;
int phi[N];
bool vis[N];
void get_phi(int n)
{
phi[1] = 1;
for(int i=2;i<=n;i++)
{
if(!vis[i])
{
p[cnt++] = i;
phi[i] = i-1;
}
for(int j=0;p[j]*i<=n;j++)
{
int m = i*p[j];
vis[m] = true;
if(i%p[j]==0)
{
phi[m] = phi[i]*p[j];
break;
}
else phi[m] = phi[i]*(p[j]-1);
}
}
return;
}
int main(void)
{
int n;cin >> n;
LL res = 0;
get_phi(n);
for(int i=1;i<=n;i++)
res+=phi[i];
cout << res << endl;
return 0;
}
如果你还是不太懂的话,建议去小破站看看董晓老师讲的算法课
飞机票:【G09 筛法求欧拉函数】https://www.bilibili.com/video/BV1VP411p7Bs?vd_source=703af51dc566d98822b7573adab52f24
感谢查看,如果对你有帮助的话,点个赞呗