首页 > 其他分享 >浅记齐肯多夫表示

浅记齐肯多夫表示

时间:2023-10-19 17:55:06浏览次数:31  
标签:bar 多夫 text 齐肯 Carry 浅记 left

齐肯多夫定理

定义斐波那契数列 \(F_0 = F_1 = 1, F_i = F_{i-2}+F_{i-1}(i\geq 2)\)。

\(x \in \mathbb N\) 的齐肯多夫表示 \(\left<c_1,c_2, \cdots,c_k\right>\) 满足 \(c_1 > 0, c_i > c_{i - 1} + 1\) 且 \(\sum_{i=1}^k F_{c_i} = x\)。

齐肯多夫定理是说,对于任意的 \(x\),这样的表示存在且唯一。

证明

存在性:我们取出最大的 \(F_i\) 满足 \(F_i \leq x\),并令 \(x' \gets x - F_i\)。此时 \(x'=x-F_i<F_{i + 1}-F_i = F_{i-1}\),从而接下来 \(x'\) 选取的数最多为 \(F_{i - 2}\)。

对于充分大的 \(F_n\),我们用一个长为 \(n - 1\) 的 \(01\) 串表示 \(F_1 \sim F_{n - 1}\) 是否被选取。显然长为 \(n - 1\) 的、没有相邻的 \(1\) 的 \(01\) 串的个数为 \(F_{n}\);同时可以归纳证明,无论我们如何选取,得到的和总是 \(< F_n\)。从而根据存在性,\([0, F_n)\) 内的每个数都有恰好一种表示。


构造一个给定自然数 \(x\) 的齐肯多夫表示是容易的,与存在性证明的归纳方法类似,\(x > 0\) 时选出最大的 \(F_i \leq x\) 并递归构造 \(x - F_i\) 即可。

齐肯多夫表示的基本运算

加法

计算 \(\left<x_1, x_2, \cdots, x_k\right> + \left<y_1, y_2, \cdots, y_k\right>\)。

先简单相加得到 \(z_i = x_i + y_i\),此时棘手的是 \(z_i \gt 1\) 的位置。

我们考虑从高位到低位逐步调整,即假设当前位为 \(i\),已经保证 \((i, k]\) 的位合法。

设 \(\text{Carry}(o)\) 表示从第 \(o\) 位开始不断向高位进位的过程,即如下代码:

void Carry(int o) {
  while (z[o] && z[o + 1]) --z[o], --z[o + 1], ++z[o += 2];
}

我们 \(\text{Carry}(i)\) 之后,不难发现若仍有 \(z_i \gt 1\),那么 \(z_{i + 1} = 0\)。

此时我们拆解 \(2F_i = F_i + F_{i - 1} + F_{i - 2} = F_{i + 1} + F_{i - 2}\),即 \(z_i \gets z_i - 2, z_{i + 1} \gets 1, z_{i - 2} \gets z_{i - 2} + 1\)。

做完上述操作后,我们仍要 \(\text{Carry}(i+1), \text{Carry}(i)\) 来保证高位的合法性。

定义势能为 \(\sum z_i\),那么 \(\text{Carry}\) 每循环一次势能就会 \(-1\),其余操作不改变势能。因此时间复杂度为 \(\mathcal O(k)\)。

减法

计算 \(\left<x_1, x_2, \cdots, x_k\right> - \left<y_1, y_2, \cdots, y_k\right>\)。保证 \(x\) 代表的数大于等于 \(y\) 代表的数。

先令 \(z_i = x_i - y_i\),美观起见用 \(\bar{1}\) 表示 \(-1\)。

我们仍然是从高位向低位调整,逐步把 \(z\) 重构成只包含 \(0, 1, 2\) 的序列,再应用加法的做法。

同时,由于 \(x \geq y\),我们任意时刻第一个非 \(0\) 位一定不是 \(\bar{1}\),因此我们只需要设计 \(1, 2\) 开头的转化即可。

\[\begin{aligned} 1\bar{1}0 \to 001 \qquad 1\bar{1}1 \to 002 \qquad 10\bar{1} \to 010 \\ 2\bar{1}0 \to 101 \qquad 2\bar{1}1 \to 102 \qquad 20\bar{1} \to 110 \end{aligned} \]

时间复杂度依旧是 \(\mathcal O(k)\)。

正则化

给定 \(N = \sum_{i=1}^n a_i F_i\),求它的齐肯多夫表示。\(n \leq 10^6, a_i \leq 10^{18}\)。

令 \(N_1 = \sum_{i=1}^n \lfloor \frac{a_i}2\rfloor F_i\),\(N_2 = \sum_{i=1}^n (a_i \bmod 2)F_i\)。

那么可以递归计算 \(N_1\),再计算 \(N = N_1 + N_1 + N_2\)。

时间复杂度 \(\mathcal O(n \log a_i)\)。

乘法

计算 \(\left<x_1, x_2, \cdots, x_k\right> \times \left<y_1, y_2, \cdots, y_k\right>\)。

标签:bar,多夫,text,齐肯,Carry,浅记,left
From: https://www.cnblogs.com/reliauk/p/zeckendorf.html

相关文章

  • 第二届猿人学web比赛第一题浅记
    上个月的猿人学逆向比赛终于参加了一次,本着嫖一件文化衫的目的与做出第一题的目标,开始了比赛。过程是艰苦的,结果还是满意的,文化衫嫖到了,现在记录一下第一题的过程。(基于补环境)链接地址:https://match2023.yuanrenxue.cn/topic/11、网站分析:照常F12看发包的请求:对比多个请求......
  • GitLab Flow浅记
    工作流Git三大特色,分支,暂存区,工作流何谓工作流    WorkFlow的字面意思,工作流,即工作流程。因为有分支的存在,才构成了多工作流的特色。事实的确如此,因为项目开发中,多人协作,分支很多,虽然各自在分支上互不干扰,但是我们总归需要把分支合并到一起,而且真实项目中涉及到很多问......
  • c#读写锁浅记录
    publicclassC{staticprivateReaderWriterLockSlimrwl=newReaderWriterLockSlim();publicstaticvoidMain(){Threadt_read1=newThread(newThreadStart(WriteSomething));t_read1.Start();Console.WriteLine("{0}C......
  • 【JS】- 排序浅记(sort)
    字母或数字,默认排序顺序为按字母升序 和array.reverse()配合可以实现倒序array.sort()在对象数据中,使用函数进行规则配置vararray=[{num:4},{num:2},{num:3}];//从小到大array.sort((a,b)=>a.num-b.num);输出:[{"num":2},{"num":3},{"num":4}]......
  • 浅记cas集成
    注意:集成单点登录后,可以完成用户认证逻,需要进一步查询用户中心接口获取用户绑定角色等信息。接入参考CAS官方Github客户端示例SpringBoot项目示例1、springboot项目在pom......
  • 基于python 的 分治算法 解决 大数乘法问题 -- 浅浅记录
    分治方法总的来说还是递归的调用,将大的问题分解为小的问题1#通过分治计算n个0的字符串2defzero(n):3ifn==0:4return""5ifn==1:......
  • 某保险影像上传接口浅记
    好久没写文章了,目前的工作基本不涉及到逆向,都快忘了还有这项技能了,刚好,最近遇到一个加密参数问题,浅记一下接口分析选择图片后上传图中请求为我们需要分析的接口以及加......