The Euler function
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5064 Accepted Submission(s): 2140
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
题目大意:
求出 a b 区间内 欧拉函数的和。
思路:
首先,什么是欧拉函数?自己百度一下记好了。
这个题也就是用到了快速筛选出 欧拉函数,大家好像都叫他 欧拉线性筛选法。
这里简单给出原理:
欧拉函数:对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。
结论:
结论:
设P是素数,
若p是x的约数,则E(x*p)=E(x)*p.
若p不是x的约数,则E(x*p)=E(x)*E(p)=E(x)*(p-1).
至于证明:
下面贴出来,可以看一下:
E(x)表示比x小的且与x互质的正整数的个数。
1 若p是素数,E(p)=p-1。
2 E(p^k)=p^k-p^(k-1)=(p-1)*P^(k-1)
证:令n=p^k,小于n的正整数数共有n-1即(p^k-1)个,其中与p不质的数共[p^(k-1)-1]个(分别为1*p,2*p,3*p...p(p^(k-1)-1))。
所以E(p^k)=(p^k-1)-(p^(k-1)-1)=p^k-p^(k-1).得证。
3 若ab互质,则E(a*b)=E(a)*E(b),欧拉函数是积性函数.
4 对任意数n都可以唯一分解成n=p1^a1*p2^a2*p3^a3*...*pn^an(pi为素数).
则E(n)=E(p1^a1)*E(p2^a2)*E(p3^a3)*...*E(pn^an)
=(p1-1)*p1^(a1-1)*(p2-1)*p2^(a2-1)*...*(pn-1)*pn^(an-1)
=(p1^a1*p2^a2*p3^a3*...*pn^an)*[(p1-1)*(p2-1)*(p3-1)*...*(pn-1)]/(p1*p2*p3*...*pn)
=n*(1-1/p1)*(1-1/p2)*...*(1-1/pn)
5 E(p^k) =(p-1)*p^(k-1)=(p-1)*p^(k-2)*p
E(p^(k-1))=(p-1)*p^(k-2)
当k>1时,E(p^k)=E(p*p^(k-1))=E(p^(k-1))*p.
(当k=1时,E(p)=p-1.)
由上式: 设P是素数,
若p是x的约数,则E(x*p)=E(x)*p.
若p不是x的约数,则E(x*p)=E(x)*E(p)=E(x)*(p-1). 证明结束。
1 若p是素数,E(p)=p-1。
2 E(p^k)=p^k-p^(k-1)=(p-1)*P^(k-1)
证:令n=p^k,小于n的正整数数共有n-1即(p^k-1)个,其中与p不质的数共[p^(k-1)-1]个(分别为1*p,2*p,3*p...p(p^(k-1)-1))。
所以E(p^k)=(p^k-1)-(p^(k-1)-1)=p^k-p^(k-1).得证。
3 若ab互质,则E(a*b)=E(a)*E(b),欧拉函数是积性函数.
4 对任意数n都可以唯一分解成n=p1^a1*p2^a2*p3^a3*...*pn^an(pi为素数).
则E(n)=E(p1^a1)*E(p2^a2)*E(p3^a3)*...*E(pn^an)
=(p1-1)*p1^(a1-1)*(p2-1)*p2^(a2-1)*...*(pn-1)*pn^(an-1)
=(p1^a1*p2^a2*p3^a3*...*pn^an)*[(p1-1)*(p2-1)*(p3-1)*...*(pn-1)]/(p1*p2*p3*...*pn)
=n*(1-1/p1)*(1-1/p2)*...*(1-1/pn)
5 E(p^k) =(p-1)*p^(k-1)=(p-1)*p^(k-2)*p
E(p^(k-1))=(p-1)*p^(k-2)
当k>1时,E(p^k)=E(p*p^(k-1))=E(p^(k-1))*p.
(当k=1时,E(p)=p-1.)
由上式: 设P是素数,
若p是x的约数,则E(x*p)=E(x)*p.
若p不是x的约数,则E(x*p)=E(x)*E(p)=E(x)*(p-1). 证明结束。
感想:
刚开始接触这方面的内容,证明还不是完全理解,会来再更新窦窦版本的证明理解!
AC代码;
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
const int MAXN=3000001;
int prime[MAXN];//保存素数
bool vis[MAXN];//初始化
int oula[MAXN];//欧拉函数
void Prime(int n)
{
int cnt=0;
memset(vis,0,sizeof(vis));
for(int i=2;i<n;i++)
{
if(!vis[i])
{
prime[cnt++]=i;
oula[i]=i-1;// 如果 i 是素数 oula[i]=i-1
}
for(int j=0;j<cnt&&i*prime[j]<n;j++)
{
__int64 k=i*prime[j];//素数与另一个数的合数不是素数
vis[k]=1; // 所以这里标记 k 不是素数。
if(i%prime[j]==0)
{
oula[k]=oula[i]*prime[j]; // 定理的应用
break;
}
else
oula[k]=oula[i]*(prime[j]-1);
}
}
}
int main()
{
int a,b;
Prime(3000000);
while(cin>>a>>b)
{
__int64 ans=0;
for(int i=a;i<=b;i++)
ans+=oula[i];
cout<<ans<<endl;
}
}