ACM常用数论之欧拉函数

数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目(φ(1)=1)。此函数以其首名研究者欧拉命名(Euler’so totient function),它又称为Euler’s totient function、φ函数、欧拉商数等。 例如φ(8)=4,因为1,3,5,7均和8互质。 从欧拉函数引伸出来在环论方面的事实和拉格朗日定理构成了欧拉定理的证明。



欧拉函数公式:euler(x) = x*(1-1/p1)(1-1/p2)……(1-1/pn),p为x的质因数。用公式法求解代码

 int euler(int n){    
     int res=n,a=n;  
     for(int i=2;i*i<=a;i++){  
         if(a%i==0){  
             res=res/i*(i-1);//先进行除法是为了防止中间数据的溢出   
             while(a%i==0) a/=i;  
         }  
     }  
     if(a>1) res=res/a*(a-1);  
     return res;  
}  

打表求法,用的比较多

void Euler()
{
     euler[1]=1;  
     for(int i=2;i<MAX;i++)  
       euler[i]=i;  
     for(int i=2;i<MAX;i++)  
        if(euler[i]==i)  
           for(int j=i;j<MAX;j+=i)  
              euler[j]=euler[j]/i*(i-1);
}

用法一 :由欧拉函数求解也可以求出,一个数x的所有质因数的和euler(n)*n/2
这里涉及到一个问题;
欧拉数在n>2时,必定为偶数
首先我们知道因数分解定理,设
证明如下。看不懂,懂这个性质就行
n=Πpi^αi
Φ(n)=Π(pi^αi-pi^(αi-1))
如果n=2^α,α≥2
则Φ(n)=2^α-2^(α-1),=2^(α-1)
为偶数;
如果n>2,而且至少有一个奇素数p
则 p^α-p^(α-1) 为偶数(α≥1)
(因为 p^α与p^(α-1) 均为奇数)
故若N>2,则Φ(N)必定是偶数.
用法二:质数n的euler(n) = n-1;
例题
hdu2824
The Euler function
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7245 Accepted Submission(s): 3005

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

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

Sample Input

3 100

Sample Output

3042

求两个数之间所有数的欧拉数的和,
即e(a)+……e(b);

#include<stdio.h>
#define MAX 3000005

__int64 euler[MAX];
void Euler()
{
     euler[1]=1;  
     for(int i=2;i<MAX;i++)  
       euler[i]=i;  
     for(int i=2;i<MAX;i++)  
        if(euler[i]==i)  
           for(int j=i;j<MAX;j+=i)  
              euler[j]=euler[j]/i*(i-1);
}

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

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值