1. 奇妙序列问题解析
最近在解决一个有趣的编程问题——"奇妙序列"的实现。这个数据结构需要支持四种操作:动态追加元素、全局加法、全局乘法以及指定下标查询。听起来简单,但要在保证效率的前提下实现这些功能,特别是当操作次数达到10^5量级时,就需要一些巧妙的优化技巧了。
问题的核心在于如何处理大规模的全局操作。如果每次全局加法或乘法都遍历整个序列进行修改,时间复杂度会高达O(n^2),这在10^5次操作下显然不可行。经过反复思考和实践,我找到了一种基于延迟计算的高效解决方案,将全局操作的时间复杂度优化到了O(1),查询操作则为O(1)或O(log MOD),完美满足题目要求。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 延迟计算思想解析
2.1 全局状态变量设计
延迟计算的核心思想是避免立即执行全局操作,而是记录这些操作的"意图"。为此,我们维护两个关键状态变量:
- 乘法系数(mul_factor):记录所有全局乘法操作的累积效果
- 加法偏移量(add_offset):记录所有全局加法操作的累积效果
初始状态下,mul_factor=1,add_offset=0。当执行全局加法操作addAll(x)时,我们并不实际修改序列中的每个元素,而是简单地将x加到add_offset上。同理,全局乘法操作multAll(x)则将mul_factor乘以x,同时add_offset也乘以x(因为加法操作也需要被乘法影响)。
这种设计使得全局操作的时间复杂度降为O(1),因为我们只是修改了两个变量,而不是遍历整个序列。
2.2 元素追加的特殊处理
当新元素val被追加到序列中时,我们需要考虑当前的全局状态。由于之前的全局操作尚未实际应用到元素上,新元素需要"预计算"其最终值。
具体来说,追加的元素val应该等于:(val - add_offset) * inv(mul_factor) mod MOD,其中inv表示模逆元。这个公式的推导基于以下思路:
- 假设元素val被追加时,已经经历了所有之前的全局操作
- 那么它的值应该是val * mul_factor + add_offset
- 为了存储原始值,我们需要反向计算:(val - add_offset) / mul_factor
- 在模运算中,除法等同于乘以模逆元
这个处理确保了无论何时查询该元
