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