您的位置:首页 > 其它

hdu 2824 The Eule Function 筛式欧拉函数

2013-07-15 11:49 183 查看


The Euler function

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2871 Accepted Submission(s): 1182



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互素的正整数的数目(其实等于仅对1而言,φ(1)=1,1被认为与任何数互素)。
编程求一个数的φ(n)显然很简单,用gcd()就可以了,但如果求一个很大范围(N)内所有数的欧拉函数值,gcd()就难以胜任了。
在网上找了一下,发现欧拉函数的一个公式:
φ(n)=n*(1-1/p1)(1-1/p2)....(1-1/pk),其中p1、p2…pk为n的所有素因子。
比如:φ(12)=12*(1-1/2)(1-1/3)=4。
利用这个就比较好求了,可以用类似求素数的筛法。
先筛出N以内的所有素数,再以素数筛每个数的φ值。
比如求10以内所有数的φ值:
设一数组phi[11],赋初值phi[1]=1,phi[2]=2...phi[10]=10;
然后从2开始循环,把2的倍数的φ值*(1-1/2),则phi[2]=2*1/2=1,phi[4]=4*1/2=2,phi[6]=6*1/2=3....;
再是3,3的倍数的φ值*(1-1/3),则phi[3]=3*2/3=2,phi[6]=3*2/3=2,phi[9]=.....;
再5,再7...因为对每个素数都进行如此操作,因此任何一个n都得到了φ(n)=n*(1-1/p1)(1-1/p2)....(1-1/pk)的运算
觉得这个“筛”还是比较好用的,以前求数的所有因子之和也是用的它。

#include <iostream>
using namespace std;
int ola[3000001];
int prime[216817];
bool isprime[3000001];

void eule()
{
    long long 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);
        }
    }
}
int main()
{
    eule();
    long long a, b;
    while(cin >> a>> b)
    {
        long long  ans = 0;
        while(a <= b)
        {
            ans +=ola[a++];
        }
        cout << ans << endl;
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: