Loading

法里数列

定义:

数学上,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+\sum\limits_{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;
}
posted @ 2020-09-18 10:10  GrayKido  阅读(510)  评论(0编辑  收藏  举报