AcWing 874. 筛法求欧拉函数-代码注释-golang
原题链接
简单
作者:
望哥
,
2020-07-17 23:40:18
,
所有人可见
,
阅读 637
package main
import "fmt"
// euler 欧拉函数 求 1~n 互质的数个数
func euler(n int, primes []int) int {
if len(primes) == 0 {
// 无质因子,则只有和1互质
return 1
}
res:=n
for _,x:=range primes{
res/=x
res*=x-1
}
return res
}
// sumEuler 求1~n之间所有数的欧拉函数值之和
func sumEuler(n int) int{
primes:=make([][]int, n+1) // 存放每一个数其对应的质因数
// 诶氏筛法 O(nloglogn): 从 `2~n`循环,找到下一个质数,筛掉这个质数倍数小于n的所有数;
st:=make([]bool, n+1) // 筛数状态
for i:=2;i<=n;i++{
if !st[i]{
for j:=i;j <= n; j+=i {
st[j] = true
primes[j] = append(primes[j], i) // 筛掉的数, 加上其质因子
}
}
}
// 计算每个数的欧拉函数加总
res:=0
for i:=1;i<=n;i++{
res+=euler(i,primes[i])
}
return res
}
func main(){
var n int
fmt.Scan(&n)
fmt.Println(sumEuler(n))
}