筛法求欧拉函数

只愿长相守 提交于 2020-02-29 11:25:49

筛法求欧拉函数

1、如果这个数是质数,1~p-1都是质数

2、如果i % primes[j] == 0,说明i是p[j]的质因子则有:

3、如果i % primes[j] != 0,pj是(i*pj)的最小质因子,则有:

Example

给定一个正整数n,求1~n中每个数的欧拉函数之和。

输入格式

共一行,包含一个整数n。

输出格式

共一行,包含一个整数,表示1~n中每个数的欧拉函数之和。

数据范围

1≤n≤1061≤n≤106

输入样例:

6

输出样例:

12
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;
const int N = 1000010;

//primes存的每一个质数, cnt存质数下标
int primes[N], cnt;
//欧拉函数
int phi[N];
bool st[N];//表示每个数是否被筛到

LL get_eulers(int n)
{
    phi[1] = 1;//定义第一个
    for (int i = 2; i <= n; i ++)
    {
        if (!st[i])//如果没被筛过
        {
            primes[cnt ++] = i;
            phi[i] = i - 1;//如果这个数是质数,1~p-1都是质数
        }
        //从小到大枚举所有质数
        for (int j = 0; primes[j] <= n / i; j ++)
        {
            st[primes[j] * i] = true;//标记已经筛过
            if (i % primes[j] == 0) //break;//一个优化变成线性
            {
                //i % primes[j] == 0,说明i是p[j]的质因子
                phi[primes[j] * i] = phi[i] * primes[j];
                break;
            }
            //如果i % primes[j] != 0,pj是(i*pj)的最小质因子
            phi[primes[j] * i] = phi[i] * (primes[j] - 1);
        }
    }
    
    LL res = 0;//定义总和
    for (int i = 1; i <= n; i ++) res += phi[i];//求总和
    return res;
}

int main()
{
    int n;
    cin >> n;
    
    cout << get_eulers(n) << endl;
    
    return 0;
}

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!