循环连分数
线性分式变换
连分数的另一个重要概念是所谓的线性分式变换(Linear fractional transformations)。
定义
线性分式变换 是一个函数
线性分式变换
线性分式变换的逆,也是线性分式变换:
DMOPC '19 Contest 7 P4 - Bob and Continued Fractions
给您一个正整数数组
如果能够连接连分数,则可以用线段树来解决这个问题。
通常情况下,
表示
因此,问题归结为计算
变换的组合是关联的,因此可以在线段树的每个节点中计算其子树中变换的组合。
例题 连分数的线性分式变换
设
从而,对任意的
如上所述,
因此,通过依次添加
由于
此外,对于
请注意,
例题 连分数算法
令
这里的想法与前面的问题类似,但不应使用
您可以将当前变换更改为
然后,检查
循环连分数
仿照循环小数的概念,如果在连分数后面形成了循环,则形成 循环连分数。
循环连分数的最小正周期一般用字母
纯循环连分数
定义
如果存在
如果
例如纯循环连分数:
混循环连分数:
混循环连分数后面循环的部分,最早循环的部分称为它的“纯循环部分”。
纯循环连分数的整数部分
对于
一方面,这个方程意味着
另一方面,使用渐进分数的公式,这个方程意味着
也就是说,
类似的推理代表了混循环连分数,即
可以进一步证明(由拉格朗日首先完成),对于具有整数系数的任意二次方程
拉格朗日连分数定理
关于循环连分数有一个特别重要的基础定理:
拉格朗日连分数定理:实二次有理数与循环连分数一一对应。
该定理最早由拉格朗日(Lagrange)于 1769 年证明。
根据余项的重复出现,证明循环连分数一定是二次有理数非常容易。重点在于证明二次有理数一定是循环连分数。
对二次有理数执行“无限简单连分数”计算,即取倒数、取整交替,得到的余数还是二次有理数。
接下来要强行刻画余项,将余项束缚在有限的范围,有限范围里的无限余项必然会发生重复。
设
如果分母不整除分子的范数,那么分子分母同时乘以分母的绝对值,并强行压入根号,在新二次有理数中,分母整除新的分子的范数。因此,任何二次有理数都能写成这形式。
根据上文的简单连分数算法:对余数取整可以得到
取整后得到的新的
由于范数为负,取倒数之后
余数
每个
例题 二次有理数
找到
对于数字的第
从而,
将分子和分母乘以
接下来求解
首先,
因此,如果表示
这种表示法的优点在于,如果将
下面是计算
```py
# compute the continued fraction of sqrt(n)
def sqrt(n):
n0 = math.floor(math.sqrt(n))
x, y, z = 0, 1, 1
a = []
def step(x, y, z):
a.append((x * n0 + y) // z)
t = y - a[-1]*z
x, y, z = z*t, -z*y, t**2 - n*x**2
g = math.gcd(x, math.gcd(y, z))
return x // g, y // g, z // g
used = dict()
for i in range(n):
used[x, y, z] = i
x, y, z = step(x, y, z)
if (x, y, z) in used:
return a
```
使用相同的“step”函数,但不同的初始
伽罗瓦连分数定理
纯循环连分数有类似于反序定理的定理。记:
则两个 x 互为“倒数负共轭”。即,若记:
则 x 与 y 共轭。
该定理最早由伽罗瓦(Galois)在他 17 岁那年(1828 年)发现并证明。
不妨改取比较长(例如至少有 5 项)的循环节。将循环节部分反序,根据反序定理,渐进分数有:
由于渐进分数的分子分母总是互素,只能分子分母对应相等。
根据纯循环,循环节的余项与它本身相等,有:
之后只需将上述反序定理代入验证即证完。
根据伽罗瓦连分数定理,纯循环连分数的共轭一定落在
如果二次有理数
对二次无理数进行连分数算法,它的余项
根据共轭落在
由拉格朗日连分数定理,x 一定是循环连分数,存在余项 r 相同,于是它们的前一个部分商 a 相同,前一个余项是小数部分的倒数,也相同。最后推得第 0 项在循环节中,该二次有理数纯循环。
根号 d 的连分数
对于非平方整数 d,有:
这是根号 d 的连分数形式。不仅最后一位是整数部分的两倍,而且中间部分还是对称的。
对于非平方整数 d,二次有理数
是纯循环连分数。于是就有:
而上述纯循环连分数的倒数负共轭既可以用伽罗瓦连分数定理表达,也可以由它本身直接表达:
根据简单连分数展开的唯一性就证明了该结论。
同样也可以证明,整数部分为半整数的相同结构:
一个实例
以
各个余项分别是:
根据伽罗瓦连分数定理,对称的余项
如果循环节
在后面的 Pell 方程一节中将指出,在根号
Tavrida NU Akai Contest - Continued Fraction
你得到了
在计算完
```py
x, k = map(int, input().split())
mod = 10**9+7
# compose (A[0]*x + A[1]) / (A[2]*x + A[3]) and (B[0]*x + B[1]) / (B[2]*x + B[3])
def combine(A, B):
return [t % mod for t in [A[0]*B[0]+A[1]*B[2], A[0]*B[1]+A[1]*B[3], A[2]*B[0]+A[3]*B[2], A[2]*B[1]+A[3]*B[3]]]
A = [1, 0, 0, 1] # (x + 0) / (0*x + 1) = x
a = sqrt(x)
T = len(a) - 1 # period of a
# apply ak + 1/x = (ak*x+1)/(1x+0) to (Ax + B) / (Cx + D)
for i in reversed(range(1, len(a))):
A = combine([a[i], 1, 1, 0], A)
def bpow(A, n):
return [1, 0, 0, 1] if not n else combine(A, bpow(A, n-1)) if n % 2 else bpow(combine(A, A), n // 2)
C = (0, 1, 0, 0) # = 1 / 0
while k % T:
i = k % T
C = combine([a[i], 1, 1, 0], C)
k -= 1
C = combine(bpow(A, k // T), C)
C = combine([a[0], 1, 1, 0], C)
print(str(C[1]) + '/' + str(C[3]))
```
贡献者:@Untitled_unrevised@Great-designer
本页面最近更新:2/3/2023, 12:00:00 AM,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用