Farey Sequence

Description

The Farey Sequence Fn for any integer n with n >= 2 is the set of irreducible rational numbers a/b with 0 < a < b <= n and gcd(a,b) = 1 arranged in increasing order. The first few are 
F2 = {1/2} 
F3 = {1/3, 1/2, 2/3} 
F4 = {1/4, 1/3, 1/2, 2/3, 3/4} 
F5 = {1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5} 

You task is to calculate the number of terms in the Farey sequence Fn.

Input

There are several test cases. Each test case has only one line, which contains a positive integer n (2 <= n <= 106). There are no blank lines between cases. A line with a single 0 terminates the input.

Output

For each test case, you should output one line, which contains N(n) ---- the number of terms in the Farey sequence Fn. 

Sample Input

2
3
4
5
0

Sample Output

1
3
5
9

Source

​POJ Contest​​,Author:Mathematica@ZSU

Time Limit: 1000MS

 

Memory Limit: 65536K

Total Submissions: 18838

 

Accepted: 7581

算法分析:

裸的欧拉函数求和问题,最后用long long 保存

代码实现

#include<cstdio>  
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
using namespace std;
const double eps = 1e-8;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const int MAXN=5010;
const int MAXM=100010;
using namespace std;
const int M=1000011;
int prime[M],mark[M];//prime是素数数组,mark为标记不是素数的数组
int tot,phi[M];//phi为φ(),tot为1~i现求出的素数个数
void getphi(int N){
phi[1]=1;//φ(1)=1
for(int i=2;i<=N;i++){//从2枚举到N
if(!mark[i]){//如果是素数
prime[++tot]=i;//那么进素数数组,指针加1
phi[i]=i-1;//根据性质1所得
}
for(int j=1;j<=tot;j++){//从现求出素数枚举
if(i*prime[j]>N) break;//如果超出了所求范围就没有意义了
mark[i*prime[j]]=1;//标记i*prime[j]不是素数
if(i%prime[j]==0){//应用性质2
phi[i*prime[j]]=phi[i]*prime[j];break;
}
else phi[i*prime[j]]=phi[i]*phi[prime[j]];//应用性质3
}
}
}


int main()
{

int n;
getphi(M);
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
long long sum=0;
for(int i=2;i<=n;i++)
{
sum+=phi[i];
}
cout<<sum<<endl;
}
return 0;
}