Stern-Brocot Tree HDU - 4556(法裏數列長度)

Stern-Brocot Tree HDU - 4556

這裏寫圖片描述

 上圖是一棵Stern-Brocot樹,其生成規則如下:
  從第1行到第n行,每行相鄰兩數a/b和c/d,產生中間數(a+c)/(b+d),置於下一行中。將一行的分數(包括0/1,1/0),進行約分簡化,則每一行(包括0/1,1/0,1/1),不會出現兩個相同的分數。若分子或者分母大於n,則去掉該分數,將剩下的分數,從小到大排序,得到數列F。
  現在請您編程計算第n行的數列F的個數。

Input
  輸入包含多組測試用例,每組輸入數據是一個正整數n(n<=1000000)。
Output
  對於每組的測試數據n,請輸出第n行的數列F的個數。
Sample Input

1
2
4
6

Sample Output

3
5
13
25

題意:

法裏數列

法裏數列長度f[n]=f[n-1]+φ(n)(這裏的長度值0-1的長度)

因爲這個題還有對稱的另一半所以只需要歐拉函數乘2即可f[n]=f[n-1]+2*φ(n)

code:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define maxn 1000005
    #define ll __int64
    ll phi[maxn],ans[maxn];
    void init()
    {
        phi[1]=1;
        for(int i=2;i<maxn;i++)
        {
            if(!phi[i])
            {
                for(int j=i;j<maxn;j+=i)
                {
                    if(!phi[j])
                        phi[j]=j;
                    phi[j]-=phi[j]/i;
                }
            }
        }
        ans[1]=3;
        for(int i=2;i<maxn;i++)ans[i]=ans[i-1]+2*phi[i];
    }
    int main()
    {
        init();
        int n;
        while(~scanf("%d",&n))
        {
            printf("%I64d\n",ans[n]);
        }
        return 0;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章