这个题目主要是算Euler函数。而且问题主要集中于怎么在时间内全部解出来。开始我所用的方法比较直接:
if n%m =0 接下来有两种情况:n = n/m ;
1. if n%m=0 , phi(n) = phi(n/m)*m;
2. if n%m!=0, phi(n) = phi(n/m)(m-1)
用循环直接一个一个计算,显然这种算法比较耗时,超时错误;
在网上看到一个同学的程序,他的思路启发了我,我代码跟他稍有些不同。主要是从小素数开始起,不断加倍,并且在循环中不断调整phi的值,最后循环完,恰好是phi;
比如,从3开始,phi(3) =2;然后 3+3=6,而6能同时被2和3整除,在循环2时,应经对phi(6)从phi(6)=6调整到phi(6)=phi(6)/i*(i-1)=3;在循环3的过程中,再调整phi(6)=phi(6)/3*(3-1)=2;
以后的数字都是按照这个过程循环下去。
代码:
#include
#include
#include
#define max 3000005
int array[max] ;
using namespace std ;
void Init()
{
for(int i=2;i
if(!array[i])
{
array[i] = i-1 ; //i is prime
for(int j=i+i;j
{
if(!array[j])
array[j]=j;
array[j]=array[j]/i*(i-1);
}
}
}
int main()
{
int a , b ;
Init();
while(scanf("%d %d",&a,&b)!=EOF)
{
long long result = 0 ;
for(int i=a;i<=b;++i)
result += array[i] ;
printf("%I64d/n",result);
}
system("pause");
return 0 ;
}