法里数列

定义:

数学上,n阶的法里数列是0和1之间最简分数的数列,由小至大排列,每个分数的分母不大于n

(F(1)={frac{0}{1},frac{1}{1}})

(F(2)={frac{0}{1},frac{1}{2},frac{1}{1}})

(F(3)={frac{0}{1},frac{1}{3},frac{1}{2},frac{2}{3},frac{1}{1}})

(F(4)={frac{0}{1},frac{1}{4},frac{1}{3},frac{1}{2},frac{2}{3},frac{3}{4},frac{1}{1}})

(F(5)={frac{0}{1},frac{1}{5},frac{1}{4},frac{1}{3},frac{2}{5},frac{1}{2},frac{3}{5},frac{2}{3},frac{3}{4},frac{4}{5},frac{1}{1}})

性质:

n阶的法里数列包(F_n)包含了较低阶法里数列的全部项,特别是包含了(F_{n-1})的全部项以及与(n)互质的每个数的相应分数,所以(F_n)(F_{n-1})的长度的关系,可以用欧拉函数(varphi(n))描述:

(|F_n|=|F_{n-1}|+varphi(n))

(|F_1|=2)可得

(|F_n|=1+sumlimits_{i=1}^{n}varphi(i))

(|F_n|)的渐进行为是:

(|F_n|=frac{3n^2}{pi^2})

关于数列相邻项

(frac{a}{b})(frac{c}{d})是法里数列的邻项,且(frac{a}{b}<frac{c}{d}),那么他们之差是(frac{1}{bd}),即(bc-ad=1)

逆命题同样成立,若(bc-ad=1),其中(a,b,c)(d)为正整数,及有(a<b,c<d)(frac{a}{b})(frac{c}{d})在阶为(max(d,b))的法里数列中是邻项​

如何生成n阶的法雷序列:

利用Stern Brocot Tree生成

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/trie_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
// freopen("k.in", "r", stdin);
// freopen("k.out", "w", stdout);
// clock_t c1 = clock();
// std::cerr << "Time:" << clock() - c1 <<"ms" << std::endl;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
mt19937 rnd(time(NULL));
#define de(a) cout << #a << " = " << a << endl
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define ls ((x) << 1)
#define rs ((x) << 1 | 1)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<char, char> PCC;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 1e3 + 7;
const ll MAXM = 4e5 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-7;
const double pi = acos(-1.0);
struct Stern_Brocot_Tree
{
    int n;
    vector<PII> SB_Tree;
    void init(int x)
    {
        n = x;
        vector<PII>().swap(SB_Tree);
        SB_Tree.emplace_back(0, 1);
    }
    void dfs(int l1, int l2, int r1, int r2)
    {
        if (l2 + r2 > n)
            return;
        dfs(l1, l2, l1 + r1, l2 + r2);
        SB_Tree.emplace_back(l1 + r1, l2 + r2);
        dfs(l1 + r1, l2 + r2, r1, r2);
    }
    void Build() //构造n阶法雷数列
    {
        dfs(0, 1, 1, 1);
        SB_Tree.emplace_back(1, 1);
    }

} SBT;
int main()
{
    SBT.init(5);
    SBT.Build();
    for (auto i : SBT.SB_Tree)
        printf("%d/%d ", i.first, i.second);
    puts("");
    return 0;
}
原文地址:https://www.cnblogs.com/graytido/p/13689669.html