题目描述
Farey序列Fn,要求计算a/b(0 < a < b <= n并且gcd(a,b)=1)的个数,例如:
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}
你的任务是计算Farey序列Fn的个数
输入格式
包含多组测试数据,每组数据仅一行为一个正整数n (2<=n<=10^6),最后一行为0作为文件的结束。
输出格式
对于每组数据输出一行为Farey序列Fn的个数。
样例数据
样例输入
2
3
4
5
0
样例输出
1
3
5
9
题目分析
分析差量,每次增加的数分子均与分母互质,故每次增加的个数为欧拉函数。
于是做个欧拉函数求和
源代码
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
inline const long long Get_Int() {
long long num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
long long n,f[1000005],Phi[1000005];
void Euler_Table(int n) { //筛选法求欧拉函数
memset(Phi,0,sizeof(Phi));
Phi[1]=1;
for(int i=2; i<=n; i++)
if(Phi[i]==0)
for(int j=i; j<=n; j+=i) {
if(Phi[j]==0)Phi[j]=j;
Phi[j]=Phi[j]/i*(i-1);
}
}
int main() {
Euler_Table(1000001);
f[1]=Phi[1];
f[2]=Phi[2];
for(int i=3; i<=1000001; i++)f[i]=f[i-1]+Phi[i];
while(true) {
n=Get_Int();
if(n==0)break;
printf("%lld\n",f[n]);
}
return 0;
}