首页 > 其他分享 >QOJ #1280.Fibonacci Partition/Fibonacci性质大杂烩

QOJ #1280.Fibonacci Partition/Fibonacci性质大杂烩

时间:2024-04-05 18:55:05浏览次数:23  
标签:Zeckendorf leftarrow cdot Partition Fibonacci las QOJ 1280

QOJ #1280.Fibonacci Partition

(为什么布置的作业题没有任何可见 AC 记录啊/kk)

拿下了 QOJ 上的用户首杀(同时目前也是 QOJ 可见的 submission 中唯一一个过掉这个题的,另一个是 vjudge 上我的提交)。

也许是这个题实在是太冷门了,但是从 Fibonacci-Lucas 数列的性质应用上是一道非常有意义的题。

题意

有一个 \(X\) 初始为 \(0\),进行 \(m\) 次操作。每次操作 \(X\leftarrow X+a\cdot F_b\),其中 \(b\) 为第 \(b\) 项 Fibonacci 数(这里的 Fibonacci 数列的定义与之前不同,\(F_1=1,F_2=2\))。每次操作后输出一个数 \(\lambda(X)\),其中 \(\lambda(x)\) 表示 \(x\) 最多可以表示成多少项不同的 Fibonacci 数之和。

\(|a|,b\le10^9,m\le5\times 10^4\)。

Sol

我们钦定 Fibonacci 数列为如下定义:

\[F_0 = 0, F_1=1,F_n=F_{n-1}+F_{n-2}\\ F_{-n}=(-1)^{n+1}F_n\\ n>0 \]

这样的定义使得对于任意一个整数 \(x\) 都满足 \(F_x=F_{x-1}+F_{x-2}\),是一个十分优雅的扩展定义。

但是下文所有有关分解或者表示法都只包括 \(n>1\) 的项。

Zeckendorf theorem, Zeckendorf's representation

描述

任意正整数都有且仅有一种方法,可以表示成若干在数列上不连续的 Fibonacci 数的和,且不包括 \(F_1\)。

证明

存在性

通常的方法是使用一种构造方法。

令正整数为 \(x\)。

从大到小枚举每个 Fibonacci 数,如果 \(F_i\le x\),则 \(x\leftarrow x-F_i\)。

然后我们通过归纳来证明。

有命题:\(\forall x : x<F_i\),\(x\) 一定可以被 \(F_2,F_3,\cdots,F_{i-1}\) 中不连续的一些数表出。

假设此命题对于 \(i\) 即以前的数成立,目前我们有 \(F_i\le x<F_{i+1}\) 即 \(F_i\le x<F_i+F_{i-1}\)。

我们要将这个命题推向 \(i+1\),因此我们考虑 \(x'\leftarrow x-F_i\),因此得到 \(x'<F_{i-1}\),所以 \(x\) 可以表示为 \(F_i+x'\),而 \(x'\) 可以被表示为 \(F_2,F_3,\cdots,F_{i-2}\) 中不连续的数之和。

因此我们通过归纳证明出了存在性。

唯一性

仍然通过上述的构造方法证明。

考虑如果要不同于上述构造的结果,那么必定有一个 \(F_i\le x\) 的时刻并没有令 \(x\leftarrow x-F_i\),因此我们只需要证明 \(\forall x : x\ge F_i\) 一定不能被表示成 \(F_{i-1},F_{i-2},\cdots,F_2\) 中不连续的数的和即可。

那么可知的是,表示的最大数应该为 \(F_i+F_{i-2}+\cdots+[2\mid i]F_2+[2\nmid i]F_3\)。

会发现无论什么情况,只要把这个数加上 \(1\),就可以从最后一个数往前合并,最后得到 \(F_i\),因此上式应该等于 \(F_i-1\)。

因此 \(\forall x:x\ge F_i\) 一定不能被表示成 \(F_{i-1},F_{i-2},\cdots,F_2\) 中不连续的数的和。

\(\Box\)

性质

容易证明 Zeckendorf's representation 一定是项数最少的分解。

而且另外一件关于这道题的性质是从这个分解到题目要求的最大分解的转化。

我们可以发现如下的转化一定是满足题目要求的:

10000101001 (Zeckendorf's representation)
10011001001
11101001001
11101110001
11101110110 (Answer)

因此我们得到已知 Zeckendorf's representation 时的一个计算贡献的方法。

  • 初始有 \(ans=0,las=1\),记 \(p_i\) 表示第 \(i\) 项分解。
  • 对于 \(p_i - las < 3\) 时,\(las\leftarrow p_i,\; ans\leftarrow ans+1\)。
  • 对于 \(p_i-las\ge 3\) 时,\(las\leftarrow p_i-1,ans\leftarrow ans+\left\lceil\frac{p_i-las}{2}\right\rceil\)。

Fibonacci-Lucas 数列

我们定义 Lucas 数列:

\[L_0=2,L_1=1,L_n=L_{n-1}+L_{n-2} \]

结论

\[L_k\cdot F_n=F_{n+k}+(-1)^kF_{n-k} \]

证明

归纳法证明。当 \(k=0,1\) 时显然成立。

假设结论在 \(\forall k' : k'<k\) 成立,则应有:

\[L_{k-1}\cdot F_n=F_{n+k-1}+(-1)^{k-1}F_{n-k+1} \\ L_{k-2}\cdot F_n=F_{n+k-2}+(-1)^{k-2}F_{n-k+2} \]

直接将两式相加得到:

\[(L_{k-1}+L_{k-2})\cdot F_n=(F_{n+k-1}+F_{n+k-2})+(-1)^k(F_{n-k+2}-F_{n-k+1}) \\ L_k\cdot F_n=F_{n+k}+(-1)^k F_{n-k} \]

\(\Box\)

用途

通过与 Zeckendorf's representation 相同的构造方法可以证明任何正整数都有 Lucas 数列上的分解(但不一定不连续)。记得只剩 \(L_0,L_1\) 时应该先考虑 \(L_0\) 再考虑 \(L_1\),因为 \(L_0>L_1\)。

因此题面中的 \(a\cdot F_b\) 可以转化成严格小于 \(2\log_2 a\) 项 Fibonacci 数之和,因此我们只需要维护 \(X\leftarrow X\pm F_y\) 即可。

数据结构维护

考虑维护 \(X\) 的 Zeckendorf's representation。

具体来说会发现不管是计算贡献还是加入,连续的 \(10\) 串形如 \(1010101\) 是会被连带影响的,因此使用 ODT 或普通平衡树维护即可。

发现可以分类讨论加入的情况:

  • \(00101010100\to 01101010100\) 的情况可以得到 \(00000000010\)。
  • \(00101010100\to 00101110100\) 的情况可以得到 \(00101000010\)。
  • \(00101010100\to 00101020100\) 的情况可以得到 \(11111110100\) 进而得到 \(10010100010\)。
  • 减法的 \(0(-1)00000\) 可以变成 \(1111\cdots 10(-1)\) ,因此往前找到第一个 \(1\) 去掉,这个 \(1\) 一定时存在的,然后把后面的连续的 \(1\) 变成 \(1010\cdots\) 的形态。

非常繁琐,因此实现较为复杂,应该有更好的实现。

时间复杂度 \(O(n\log_2^2 V)\),\(V\) 为值域。

Code

Submission #372257 - QOJ.ac

标签:Zeckendorf,leftarrow,cdot,Partition,Fibonacci,las,QOJ,1280
From: https://www.cnblogs.com/imcaigou/p/18116052

相关文章

  • Fibonacci
    Fibonacci思路可以发现,连续的三个字母不全相同,所以|s|\(\le\)3*|t||S|枚举一下即可(好像能证明但是不会),1e6左右所以只要暴力算出来一段S,然后枚举起点开始匹配即可40分\(O(|S|*|s|)\)枚举即可100分使用类似倍增的方法st[i][j]表示从t[i]......
  • 佳佳的 Fibonacci
    和lyh想的差不多,我认为我写的会更详细一些。dyc好厉害。完全想不到这样的做法。给你两个整数\(n\),\(m\),让你求以下式子的值。\[T(n)=\sum_{i=1}^{n}f(i)\timesi\bmodm\]对于斐波那契数列\(f(n)=f(n-1)+f(n-2)\)这样的性质,使用前缀和化简式子是个好东西。式子就变......
  • lightdb 支持 merge partitions
    背景Oracle中支持很多种分区管理操作。其中mergepartitions会将多个连续分区合并成一个分区。lightdb24.1中支持了该功能。mergepartitions功能支持list和range分区,不支持hash分区。用例range分区CREATETABLEmeasurement(city_idintnotnul......
  • Fibonacci
    #1.Recursionslowdeffibonacci_recursion(n):ifn<=1:returnnelse:returnfibonacci_recursion(n-1)+fibonacci_recursion(n-2)#2.Listsaveeveryvalue,avoidrepeatecomputefastdeffibonacci_list(n):F=[0,1]if......
  • Fibonacci数列
    1.Fibonacci数列-蓝桥云课(lanqiao.cn)题目描述:Fibonacci数列:第1、2项均为1,从第3项开始,每一项都是前两项之和。输入n值,输出Fibonacci数列第n项,该数列前10项为1,1,2,3,5,8,13,21,34,55。输入描述:输入占一行,为n的值,1sns40。输出描述:输出占一行,为Fibonacci数列第n项......
  • 戴尔windows服务器安装双系统报错For a UEFI installation, you must include an EFI
    安装centos7.9的分区时候,提示:ForaUEFIinstallation,youmustincludeanEFISystemPartitiononaGPT-formatteddisk,mountedat/boot/efi网上有好多人说修改bios,用常规的usb去启动,不要UEFI的方式,但我的windows系统已经是GPT格式,且原来就有一个EFI,所以我还是用UEFI的方......
  • Spark中driver、executor、job、stage、task、partition你懂吗?
        对于一个要提交到大数据集群的spark任务而言,准确说这个任务应该叫一个application,因为application是分布式任务,因此需要分配到多台机器中运行,而为了方便每个application的自我管理,这个多台机器中会有一台机器被选为小组长来管理整个application,而这个小组长的名字......
  • 1、postgres通过partition做表分区
    目录postgres通过partition做范围表分区1、安装pg_partman扩展2、创建需要分区表,按学生的入学时间分区3、创建分区4、插入数据5、查询分区表6、不需要子分区时7、直接插入子分区表时。8、navicat可以查看到分区的表与分区的维度postgres通过partition做范围表分区表分区是将一个......
  • <sa8650>sa8650 partition-之-新增分区加img
    <sa8650>sa8650partition-之-新增分区加img一、前言二、新增分区2.1新增用户分区2.2生成新分区文件2.3确认新分区文件2.4rawprogram文件参数解析2.5新增分区验证三、镜像文件3.1新增water.img编译脚本3.2新增water.img编译脚本运行3.3新增water......
  • Clique Partition
    哎,就差一个考虑上下界啊!来看看官解首先一个连通块的大小不可能超过\(k\),比较显然当\(n>k\)的时候,我们将点连续的分成\(\lceil\frac{n}{k}\rceil\)个,然后考虑\(n=k\)的情形官解是这么分权值的其实我考试的时候想出来这个的,手搓几次样例就可以发现了。。但是我却没有利用上......