题目描述
给定一个正整数$n$,求$1$~$n$中每个数的欧拉函数之和。
数据范围:$1≤n≤10^6$
$1$~$N$中与$N$互质的数的个数被称为欧拉函数,记为$ϕ(N)$。
若在算数基本定理中,$N=p_1^{\alpha_1}p_2^{\alpha_2}···p_k^{\alpha_k}$,则:
$ϕ(N) = N∗\frac{p_1-1}{p_1}∗\frac{p_2-1}{p_2}∗…*\frac{p_k-1}{p_k}$
线性筛法同时求欧拉函数
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 1000010;
int primes[N], cnt;
int phi[N];
bool st[N];
void get_eulers(int n)
{
phi[1] = 1;
for (int i = 2; i <= n; i++)
{
if (!st[i])
{
primes[cnt++] = i;
phi[i] = i - 1;
}
for (int j = 0; primes[j] <= n / i; j++)
{
st[primes[j] * i] = true;
if (i % primes[j] == 0)
{
phi[primes[j] * i] = phi[i] * primes[j];
break;
}
phi[primes[j] * i] = phi[i] * (primes[j] - 1);
}
}
}
int main()
{
int n;
cin >> n;
get_eulers(n);
LL res = 0;
for (int i = 1; i <= n; i++) res += phi[i];
printf("%lld\n", res);
return 0;
}
代码解释:
- 质数$i$的欧拉函数即为
phi[i] = i - 1
:1 ~ $i-1$均与$i$互质,共$i-1$个。 phi[primes[j] * i]
分为两种情况:
①i % primes[j] == 0
时:primes[j]
是i
的最小质因子,也是primes[j] * i
的最小质因子,因此1 - 1 / primes[j]
这一项在phi[i]
中计算过了,只需将基数$N$修正为primes[j]
倍,最终结果为phi[i] * primes[j]
。
②i % primes[j] != 0
:primes[j]
不是i
的质因子,只是primes[j] * i
的最小质因子,因此不仅需要将基数$N$修正为primes[j]
倍,还需要补上1 - 1 / primes[j]
这一项,因此最终结果phi[i] * (primes[j] - 1)
。
# orz
orz
orz
orz
orz
orz
or2
# or2
这题解,看着舒服
这里解释一下为什么i不能被p[j]整除的情况下,i与p[j]互质。
因为p[j]是质数,其约数只有1和自身,i不能整除p[j],所以对于i和p[j]来说的最大公约数只有1,所以互质。
# ORZZZZZZZZZZ
orz
%%%%%
orz
tql orz
zro 番茄 orz
为什么没有初始化cnt呢?
考虑尝试 快速幂+ml素性测试+fd+tho断环得到所有的因子,再直接套欧拉公式即可
快速幂+ml素性测试
fd+tho断环
欧拉公式直接法
感谢大佬,理解啦
写的太清楚了,比我自己总结的清楚太多了,直接抄了
南京邮电to东南 厉害的
or2
orz
泰裤辣orz
orz
牛
or2