如何正确使用 RMQ
本文是笔者上语文课的时候想出来的。后来知道实际上这个东西就是 Four-Rasian。所以仅供参考吧。
序列分块。设块长为 。每块预处理出最大值。对于询问 ,答案就是整块最大值和散块最大值拼起来。答案显然是 。这是普通分块。
我们预处理出每个散块的前缀最大值和后缀最大值。预处理线性。对于跨越两个块的询问就是 。但是缺点是对于左右端点在一个块内的询问不好处理,复杂度为 。根号平衡后还是 。
我们开一个数组 ,表示第 个块到第 个块中最大值的最大值。这个数组显然可以很容易的 求出。接下来我们预处理所有长度为 的段的最大值。用单调队列也很容易做到 。这样对于左右端点在同一个块内的询问,其长度一定小于 。我们可以直接查表。对于跨越多个块的情况,可以查一下 数组。这样复杂度是 的。根号平衡一下发现当 的时候有最小值 。
这似乎是根号算法的极限?
我们考虑 算法。首先是众所周知的 ST 表。复杂度 ,全方位吊打分块TNT。
我们考虑优化这个算法。考虑分块。不妨还设块长为 。散块还是求出前后缀的 ,整块之间做一下 ST 表。跨越多块的做法可以做到 。对于单块之间的询问我们沿袭上面分块的思路,直接预处理所有长度为 的区间的 ,这样就可以直接查表。所以复杂度就是 。根号平衡一下发现当 的时候就可以达到 。这比传统意义上的 ST 表要快了。
考虑继续优化这个算法。我们发现瓶颈在处理左右端点在同一块内的答案。在每块内再做一遍 ST 表。这样就需要 的时间。剩下的算法和原来一样。预处理就变成了 了。我们让 的时候就已经做到了 了。当然块长显然可以比这个优秀,但是我不会求了。
这个做法不是很好。我认为做法 虽然渐进复杂度更劣但是完全有实力吊打做法 。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库