HDU2824--The Euler function(欧拉函数)

Problem Description

The Euler function phi is an important kind of function in number theory, (n) represents the amount of the numbers which are smaller than n and coprime to n, and this function has a lot of beautiful characteristics. Here comes a very easy question: suppose you are given a, b, try to calculate (a)+ (a+1)+....+ (b)

Input

There are several test cases. Each line has two integers a, b (2<a<b<3000000).

Output

            Output the result of (a)+ (a+1)+....+ (b)

Sample Input

3 100

Sample Output

3042

Source

2009 Multi-University Training Contest 1 - Host by TJU

Recommend

gaojie

思路:

欧拉函数的定义:

φ(n)为小于n且与n互质的数的个数

欧拉函数有一个公式

其中pi为x的质因子,x不等于0

由此,可以用类似求素数的筛法

样例代码(来自百度百科):

/*线性筛O(n)时间复杂度内筛出maxn内欧拉函数值*/
int m[maxn],phi[maxn],p[maxn],pt;         //m[i]是i的最小素因数,phi[i]是i的欧拉函数的值,p是素数,pt是素数个数
 
int make()
{
    phi[1]=1;
    int N=maxn;
    int k;
    for(int i=2;i<N;i++)
    {
        if(!m[i])//i是素数
            p[pt++]=m[i]=i,phi[i]=i-1;
        for(int j=0;j<pt&&(k=p[j]*i)<N;j++)
        {
            m[k]=p[j];
            if(m[i]==p[j])//为了保证以后的数不被再筛,要break
            {
                phi[k]=phi[i]*p[j];
/*这里的phi[k]与phi[i]后面的∏(p[i]-1)/p[i]都一样(m[i]==p[j])只差一个p[j],就可以保证∏(p[i]-1)/p[i]前面也一样了*/
                break;    
            }
            else
                phi[k]=phi[i]*(p[j]-1);//积性函数性质,f(i*k)=f(i)*f(k)
        }
    }
}

下面的是A题代码

#include<bits/stdc++.h>
using namespace std;

int ola[3000001];//存储欧拉函数的值
int prime[216817];
bool isprime[3000001];

int main()
{
    __int64 n, a, b, i , j, k = 0;
    for(i = 2; i < 3000001; i++)
    {
        if(!isprime[i])
        {
            ola[i] = i-1;
            prime[++k] = i;
        }
        for(j = 1; j <= k && prime[j]*i < 3000001; j++)
        {
            isprime[prime[j] * i] = 1;
            if(i % prime[j] == 0)
            {
                ola[prime[j]*i] = ola[i] * prime[j];
                break;
            }
            else ola[prime[j] * i] = ola[i] * (prime[j]-1);
        }
    }
    while(cin >> a >> b)
    {
        __int64 ans = 0;
        while(a <= b)
        {
            ans += ola[a++];
        }
        cout << ans << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/liuzhanshan/p/6285713.html