CEOI 2018 Day2 A. Fibonacci Representations
纯靠直觉做题,好像猜对了。
一个直觉是记 \(S = \sum_{i} \operatorname{fib}(a_{i})\),并把 \(S\) 拆成一个极大的集合 \(T\) 满足 \(\sum\limits_{i\in T} \operatorname{fib}(i) = S\),然后考虑把 \(T\) 中的元素往下展开得到所有的可能集合。
接下来的元素都指代的是 \(\operatorname{fib}\) 中的下标。后面会用到的公式有 \(x + (x + 1) = (x + 2), 2x = x + (x - 1) + (x - 2) = (x + 1) + (x - 2)\)。
首先考虑一个元素 \(x\) 可以怎么展开。
- 展开 \(x\):\(x - 1, x - 2\)。
- 展开 \(x - 2\):\(x - 1, x - 3, x - 4\);展开 \(x - 1\):\(x - 2, x - 2, x - 3\),这等价于 \(x - 1, x - 3, x - 4\),直观感受下这样做是没有必要的,故始终只会展开最小的项。
- 展开 \(x - 4\):\(x - 1, x - 3, x - 5, x - 6\)。
- ……
考虑 \(8, 4\) 的情况:
- \(8\to 7, 6\to 7, 5, 4\to 7, 5, 3, 2\);\(4\to 3, 2\)。
- 会发现对于 \(8\to 7, 5, 3, 2\) 且 \(4\to 4\),完全可以用 \(8\to 7, 5, 4\) 且 \(4\to 3, 2\) 平替。所以 \(8\) 一旦把 \(4\) 展开了,可以等价于去展开 \(4\)。
这说明对于两个奇偶相同的 \(x > y\),\(x\) 的展开可以压缩到最多恰好展开出 \(y\)。
于是对于原题的 \(a_{i}\) 均为偶数的部分分,假设现在就对 \(a_{1\sim n}\) 求解答案,降序排序后做以下 dp:
- 记 \(f_{i, 0 / 1}\) 表示当前展开 \(i\),\(a_{i - 1}\) 是否有展开出 \(a_{i}\) 的方案数(如果展开出了 \(a_{i}\) 则 \(a_{i}\) 必须向下展开)。记 \(d = a_{i} - a_{i + 1}\),转移为 \(f_{i + 1, 0} = f_{i, 0}\times \frac{d}{2} + f_{i, 1}\times (\frac{d}{2} - 1), f_{i + 1, 1} = f_{i, 0} + f_{i, 1}\)。
\(i\to i + 1\) 的转移可以写成 \(2\times 2\) 的矩阵形式,故可以做到 \(\mathrm{O}(n\log n)\)。
接下来再来考虑奇偶不同的情况,例如 \(8, 5\):
- \(8\to 7, 6\to 7, 5, 4\to 7, 5, 3, 2\);\(5\to 4, 3\to 4, 2, 1\)。
- 若 \(8\to 7, 5, 4\) 且 \(5\to 5\),则 \(7, 5, 5, 4\to 7, 6, 5\) 或 \(7, 5, 5, 4\to 7, 6, 4, 3\),会发现这都可以拆成 \(7\to 6, 5\) 且 \(5\to 5\to 4, 3\) 的情况。于是可以认为 \(8\) 至多展开到 \(5 + 1 = 6\)。
这说明对于奇偶不同的 \(x > y\),\(x\) 的展开可以压缩到最多恰好展开 \(y + 1\)。
还是沿用上面的 dp 状态,记 \(d = x - y\),有转移 \(f_{i + 1, 0} = f_{i, 0}\times \frac{{d + 1}}{2} + f_{i, 1}\times \frac{{d - 1}}{2}, f_{i + 1, 1} = 0\)。
不妨考虑一下什么样的 \(T\) 是极大的,因为 \(x, x + 1\) 和 \(x, x\) 都是可以调整的,感受一下若 \(T\) 中元素差都 \(\ge 2\) 时 \(T\) 无法调整就是极大的了。
这个时候对应原题可以解决 \(n, a_{i}\le 100\)(暴力拆出 \(T\))和 \(a_{i}\) 为不同的平方数(\(j^2 - i^2 = (j + i)(j - i)\ge 3\),所以 \(a_{i}\) 集合直接就是 \(T\))的部分了。
不过当 \(a_{i}\le 10^9\) 且不存在性质时 \(T\) 无法快速得出,于是考虑直接维护 \(T\) 的情况,加入 \(x\) 会出现以下情况:
- 若 \(x + 1\in T\),则合并成 \(x + 2\),进一步的可能会有 \(x + 3\in T\),于是 \(x\gets x + 2\)。
- 若 \(x - 1\in T\),则合并成 \(x + 1\)。(注意顺序不能改变,对于 \(x - 1, x, x + 1\) 应当直接合并出 \(x - 1, x + 2\),若先合并小的会 \(\to x + 1, x + 1\to x - 1, x + 2\),出现了更复杂的要考虑的情况。)
- 若 \(x\in T\),则 \(x, x\) 分解成 \(x - 2, x + 1\),进一步的还可能出现 \(x - 2\),所以找到 \(k_{\max}\) 满足 \(\forall i\in [0, k], x - 2k\in T\),最后会分解出 \(x - 2(k_{\max} + 1), x - 2k_{\max} + 1, \cdots, x + 1\),需要注意两个边界可能会与周边的值进行合并,还需进一步判断。
直接实现这个调整的操作可以做到 \(\mathrm{O}(n^2)\)。
考虑到前两种操作合并后元素个数都 \(-1\),所以可以直接暴力删除重算贡献。对于最后一种操作可以看作是 \(\forall i\in [1, k_{\max}]\),把 \(x - 2i\) 均 \(+1\)(平移),删除 \(x\),并加入 \(x - 2(k_{\max} + 1), x + 1\)(这样拆分的好处是之后只需要检验合并)。而 \(x - 2i\) 这一部分均平移,dp 的系数矩阵只与相邻两值差相关,所以中间的系数矩阵均没变化,只有插入的两个值附近的系数会改变。故用平衡树维护 \(T\) 即可。
时间复杂度 \(\mathrm{O}(n\log n)\)。
代码好难难难难难难难难难难难难难难写。 https://qoj.ac/submission/3215531 。

浙公网安备 33010602011771号