版权声明:点个关注(^-^)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
资源
推荐
高洁| 我们已经为您精心挑选了几个类似的问题: 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;
}