【POJ2478】Farey Sequence
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\)
輸出格式
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}^n\sum_{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\n",fd(n)-1);
}
return 0;
}