定义:
数学上,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;
}