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
2009 Multi-University Training Contest 1 - Host by TJU
Recommend
gaojie
思路:
欧拉函数的定义:
φ(n)为小于n且与n互质的数的个数
欧拉函数有一个公式
其中pi为x的质因子,x不等于0
由此,可以用类似求素数的筛法
样例代码(来自百度百科):
/*线性筛O(n)时间复杂度内筛出maxn内欧拉函数值*/ int m[maxn],phi[maxn],p[maxn],pt; //m[i]是i的最小素因数,phi[i]是i的欧拉函数的值,p是素数,pt是素数个数 int make() { phi[1]=1; int N=maxn; int k; for(int i=2;i<N;i++) { if(!m[i])//i是素数 p[pt++]=m[i]=i,phi[i]=i-1; for(int j=0;j<pt&&(k=p[j]*i)<N;j++) { m[k]=p[j]; if(m[i]==p[j])//为了保证以后的数不被再筛,要break { phi[k]=phi[i]*p[j]; /*这里的phi[k]与phi[i]后面的∏(p[i]-1)/p[i]都一样(m[i]==p[j])只差一个p[j],就可以保证∏(p[i]-1)/p[i]前面也一样了*/ break; } else phi[k]=phi[i]*(p[j]-1);//积性函数性质,f(i*k)=f(i)*f(k) } } }
下面的是A题代码
#include<bits/stdc++.h> using namespace std; int ola[3000001];//存储欧拉函数的值 int prime[216817]; bool isprime[3000001]; int main() { __int64 n, a, b, 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); } } while(cin >> a >> b) { __int64 ans = 0; while(a <= b) { ans += ola[a++]; } cout << ans << endl; } return 0; }