hdu2824 欧拉函数入门题及欧拉函数性质总结

版权声明:点个关注(^-^)V https://blog.csdn.net/weixin_41793113/article/details/89047008

欧拉函数 O(sqrt(n)) 

int Euler(int n){
    int ans = n;

    for(int i=2;i*i<=n;i++){
        if(n%i==0){
            ans = ans/i*(i-1);
            while(n%i==0)
                n/=i;
        }
    }
    if(n>1)
        ans = ans/n*(n-1);

    return ans;
}

 欧拉函数打表法

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);

}

ACM:数论专题(5)——欧拉函数https://blog.csdn.net/octopusflying/article/details/5139920

  • 定理1:若:k为素数,那么:φ(k) = k-1
  • 定理2:若:p是素数,且n = p^k,那么φ(n) = (p-1)*p^(k-1)
  • 定理3:若:p, q互质,那么:φ(p*q) = φ(p) * φ(q)

(p为质数) 
1.phi[p]=p-1,因为1-p中只有p与本身不互质。 
2.如果i mod p = 0,则 phi[i*p] = p *phi[i] 。 
3.如果i mod p != 0,则 phi[i*p] = (p-1) *phi[i] 。

下面给出欧拉函数的线性筛选代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 1000000+5 //1e6+5

using namespace std;
int phi[maxn];

void get_phi()
{
       memset(phi,0,sizeof(phi));
       phi[1] = 1;
       for(int i=2;i<=maxn;i++)
       {
           if(!phi[i])
               for(int j=i;j<=maxn;j+=i)
               {
                    if(!phi[j])
                        phi[j] = j;
                    phi[j] = phi[j]/i*(i-1);//先除再乘
               }
       }
}

 

hdu2824 The Euler function

 

问题描述

欧拉函数phi是数论中的一种重要函数,(n)表示小于n且与n互质的数量,并且该函数具有许多优美特征。这里有一个非常简单的问题:假设你给a,b,试着计算(a)+(a + 1)+ .... +(b)

输入

有几个测试用例。每行有两个整数a,b(2 <a <b <3000000)。

产量

输出(a)+(a + 1)+ .... +(b)的结果

样本输入

3 100

样本输出

3042

资源

2009年多校区培训大赛1 - 由TJU主办

推荐

高洁| 我们已经为您精心挑选了几个类似的问题:   2818  2825  2817  2822  2821 

 

这题需求多次Euler,打表法只需求一次,另外数据比较大,所以要用__int64  scanf("%lld",&a);printf("%lld",a);

#include<iostream>
#include<cstdio>
#include<stdio.h>
using namespace std;

#define MAX 3000000+5
__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(){
    int a,b;
    Euler();
    while(~scanf("%d%d",&a,&b)){
        __int64 ans=0;
        for(int i=a;i<=b;i++)
                ans+=euler[i];
        printf("%lld\n",ans);
    }
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41793113/article/details/89047008