您的位置:首页 > 其它

【HDOJ 2824】 The Euler function (欧拉筛)

2015-09-17 19:54 323 查看
【HDOJ 2824】 The Euler function (欧拉筛)


The Euler function

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

Total Submission(s): 4594 Accepted Submission(s): 1922



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 | We have carefully selected several similar problems for you: 2818 2825 2817 2822 2821



欧拉筛模板题 刚学欧拉找来做 发现自己板子跑的慢好多 百度来了个配合素数筛的板子 飞一般的感觉

素数筛附带求欧拉的主要原理就是 对于euler(x)

x为素 euler[x] = x-1;

x = y*_p && y%_p != 0 即p为新素数 由于 euler(y) = y(1-1/p1)(1-1/p2)...(1-1/pi) 因此 euler(x) = y*_p(1-1/p1)(1-1/p2)...(1-1/pi)(1-1/_p) = y(1-1/p1)(1-1/p2)...(1-1/pi)(_p-1) = euler(y)*(_p-1)

x = y*_p && y%_p == 0 即p为y的质因子 由于 euler(y) = y(1-1/p1)(1-1/p2)...(1-1/pi) 因此 euler(x) = y*_p(1-1/p1)(1-1/p2)...(1-1/pi) = euler(y)*_p

代码如下:

//弱渣筛法
#include <bits/stdc++.h>
#define ll long long

using namespace std;

//int Euler(int x)
//{
//    int i,ans = x;
//
//    for(i = 2; i*i <= x; ++i)
//    {
//        if(x%i) continue;
//        ans = ans/i*(i-1);
//        while(x%i == 0) x /= i;
//    }
//    if(x-1) return ans/x*(x-1);
//    return ans;
//}

int euler[3333333] = {0};
void InitEuler()
{
    int i,j;
    for(i = 2; i < 3000000; ++i)
    {
        if(euler[i]) continue;
        euler[i] = i-1;
        for(j = i*2; j < 3000000; j += i)
        {
            if(!euler[j]) euler[j] = j;
            euler[j] = euler[j]/i*(i-1);
        }
    }
}

int main()
{
    int i,j,a,b;
    ll sum;
//    euler[2] = 1;
//    for(i = 3; i < 3000000; ++i)
//    {
//        euler[i] = Euler(i)+euler[i-1];
//    }

    InitEuler();

    while(~scanf("%d %d",&a,&b))
    {
        sum = 0;
        for(i = a; i <= b; ++i) sum += euler[i];
        printf("%I64d\n",sum);
    }
    return 0;
}


大犇素数欧拉筛
#include<stdio.h>
#include<stdlib.h>
int  num[3000024],prime[220000];
bool isprime[3000024]={0};
void eular( )
{
   int count=0;
   __int64 k;
   for( int i=2; i<=3000000; i++ )
   {

       if( !isprime[i] )
       {
           prime[++count]=i;
           num[i]=i-1;    
       } 
       for( int j=1; j<=count&&( (k=prime[j]*i)<=3000000 );j++  )
       {
            isprime[k]=1;
            if( i%prime[j]==0 )
            {
                num[k]=num[i]*prime[j];    
            } 
            else num[k]=num[i]*( prime[j]-1 );    
       }    
   }      
}
int main( )
{
    int n,m;
    eular();
    while( scanf( "%d%d",&n,&m )!=EOF )
    {
       __int64 ans=0;
       for( int i=n; i<=m; i++ )
          ans+=num[i];
        printf( "%I64d\n",ans );       
    }
    return 0;    
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: