区间半群查询与 Ackermann 函数

最近在思考半在线卷积的复杂度有没有可能进一步优化, 决定先理清类似的问题以寻求经验.

一区间合并

如果询问的时候不能进行半群运算, 显然我们需要在预处理阶段处理所有答案, 必须进行 O(n2) 次计算.

二区间合并

如果询问的时候可以进行一次半群运算, 则可以把序列每次在中点处折开, 处理中点到两边的信息, 然后剩下的递归下去.

这样预处理的时间是 O(nlogn), 询问只需要 1 次询问.

四区间合并

先把序列分成 n/logn 个大小为 logn 的块, 消耗 O(n) 的时间处理出每个块前缀和后缀的信息.

询问的时候, 如果端点在同一个块里, 则直接考虑子问题里的情况. 否则取两端块的前后缀信息, 拼上一个对块预处理的二区间结构. 这是个四区间合并.

由于我们现在是对一个 n/logn 大小的数组做二区间合并的信息预处理, 时间是 O(n) 的, 然后要对每个小块递归下去, 所以时间复杂度是 T(n)=O(n)+(n/logn)T(logn). 也就是 n 乘以这个递归的深度, 即 O(nlogn).

查询只需要 3 次运算.

2k 区间合并

我们已经积累了足够的经验, 可以考虑攻克一般的 2k 了.

我们考虑定义 n=T(m,k) 是这样一个函数: n 是递归确定的数, 满足: 查询是 2k 区间合并的时候, 长度 n 的数列可以只用 mn 次运算.

对于二区间合并而言, 分治一个 2 的数组, 在顶层需要消耗 22 次运算. 总共的运算次数就是 (2)2+2(1)2, 我们可以取 n=2m+1. 于是令

T(m,1)=2m+1.

接下来考虑 2k 区间合并. 回忆我们的策略是把序列切成很多个块, 块形成的数列用 2(k1) 区间合并的数据结构来做. 设 n=nL, 其中 n 是块形成的数列长度, 我们接受 L 时间的预处理, 所以 n=T(L,k1). 但还需要前后缀的维护, 现在扫一层的时间是 3n. 所以令 L=T(m3,k).

现在我们重新理一遍思路:

对于 n=nL, 对于每个落在大小为 L 的块, 我们给每个块分配 (m3)L 的预处理时间, 所有块的预处理时间只和不超过 (m3)n. 对于 n 大小的块, 我们花了 2n 时间预处理所有前后缀, 外加 nL=n 的时间预处理它的 2(k1) 区间合并的结构.

于是我们有

T(m,k)=T(m3,k)T(T(m3,k),k1).

最后补一下边界情况, 不妨直接让 T(0,k)=T(1,k)=T(2,k)=2k.

那么对于 nT(m,k), 可以在 mn 次预处理的情况下支持每次查询 2k1 次操作.

Ackermann 函数

不妨令 m=3p, 然后让 T 的输出缩小到 1/3 量级, 记为新的函数 S(p,k).

由于 T(3p,1)=23p+123p13, 所以令 S(p,1)=23p1.

对于递归式, 由于 T(3p,k)T(T(3p3,k),k1), 令 S(p,k)=S(S(p1,k),k1).

再对于 k2, 令边界条件 S(0,k)=2k/3.

现在整理我们的定义:

S(p,1)=23p1.

S(0,k)=2k/3.

S(p,k)=S(S(p1,k),k1).

回顾 Ackermann 函数 A(m,n) 的定义:

A(0,n)=n+1,

A(m+1,0)=A(m,1),

A(m+1,n+1)=A(m,A(m+1,n)).

只要证明存在 c 使得 S(cn,cn)>A(n,n), 就可以证明: n 次询问只需要 O(nα(n)) 次半群运算了.

(鸽)

posted @   EntropyIncreaser  阅读(727)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2022-08-12 [SDOI / SXOI2022] 多边形 解析
点击右上角即可分享
微信分享提示