Farey Sequence
题目描述
The Farey Sequence Fn for any integer (n) with (n ge 2) is the set of irreducible rational numbers (a/b) with (0 < a < b le n)and (gcd)((a,b))$ = 1$ arranged in increasing order. The first few are
(F_2 = {1/2})
(F_3 = {1/3, 1/2, 2/3})
(F_4 = {1/4, 1/3, 1/2, 2/3, 3/4})
(F_5 = {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.
输入格式
There are several test cases. Each test case has only one line, which contains a positive integer (n) ((2 ge n ge 10^6)). There are no blank lines between cases. A line with a single (0) terminates the input.
输出格式
For each test case, you should output one line, which contains (N)((n)) ---- the number of terms in the Farey sequence (F_n).
样例输入
2 3 4 5 0
样例输出
1 3 5 9
题解
(F_n=sum_{i=1}^nsum_{j=i+1}^n[gcd(i,j)==1])
我们假设(f_n)为(n)以内(gcd)为(1)的对数,视((i,j))和((j,i))相同,包括((1,1))。
那么(n)以内(gcd)为(2)的对数为(f_{n/2})
以此类推,(n)以内(gcd)为(i)的对数为(f_{n/i})
那么我们可以得到如下等式:
(sum_{i=1}^nf_{n/i}=sum_{i=1}^ni=n*(n+1)/2)
因为(f_n)中((i,j))和((j,i))不重复计算,所以上述等式成立。
我们再把等式左边的(f_n)提出来,
(f_n=n*(n+1)/2-sum_{i=2}^nf_{n/i})
那么我们就得到了(f_n)的递推式,我们考虑到(f_n=F_n+1),因为题目中要求不包含((1,1))
所以我们可以用递推式求(f_n),因为(n le 10^6),所以我们记忆化一下就可以过了。
ps:据说也可以用欧拉函数前缀和做,这里就不多讲了QWQ。
#include<cstdio>
using namespace std;
int n;
long long f[1000009];
long long fd(long long x){
if(f[x]!=0) return f[x];
f[x]=x*(x+1)/2;
for(long long i=2;i<=x;i++){
f[x]-=((x/(x/i))-i+1)*fd(x/i);//因为一段区域内x/i相等,fd(x/i)相等,所以可以优化一下
i=x/(x/i);
}
return f[x];
}
int main(){
f[1]=1;
while(1){
scanf("%d",&n);
if(n==0) break;
printf("%lld
",fd(n)-1);
}
return 0;
}