关于三维莫队问题的一些思考和探究

本文从二维莫队算法出发,探讨如何将该算法扩展至三维情况,并通过合理的排序策略优化三次元函数查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景介绍

首先,我是一名菜鸡。
前几天在做bzoj 5283时,经过转化后需要处理这样一个二元函数
S(x,y)=∑i=1xCyiS(x,y)=\sum^{x}_{i=1} C^i_yS(x,y)=i=1xCyi
其中有QQQ组询问,x≤y≤2.5×105,Q≤2.5×105x\le y\le 2.5\times 10^5, Q\le 2.5\times 10^5xy2.5×105,Q2.5×105.
做法是:我们发现这个函数的重要性质是,假如已知S(x,y)S(x,y)S(x,y), 那么我们可以在O(1)O(1)O(1)的时间内转移得到S(x+1,y),S(x−1,y),S(x,y+1),S(x,y−1)S(x+1,y), S(x-1,y), S(x,y+1), S(x,y-1)S(x+1,y),S(x1,y),S(x,y+1),S(x,y1).
于是,我们依照莫队的思想,将所有询问离线下来。
对于询问S(x1,y1),S(x2,y2)S(x_1,y_1), S(x_2,y_2)S(x1,y1),S(x2,y2) 按如下的规则进行比较排序:
首先比较x1n\frac{x_1}{\sqrt n}nx1x2n\frac{x_2}{\sqrt n}nx2的值,小的在前。
如果这两个值相同的话,再比较y1y_1y1y2y_2y2.
从一个询问跳到另一个询问时,我们直接暴力一个一个地把左端点从x1x_1x1移到x2x_2x2, 右端点从y1y_1y1移至y2y_2y2.
这样对所有询问排序后 ,我们计算左右端点的移动总距离。假设Q,nQ,nQ,n同阶。
左端点移动距离T1T_1T1: 对于每个大小为n\sqrt nn的块,左端点一定要在块内移动。每次移动的距离不超过n\sqrt nn, 每个块内移动的总次数不超过nnn (nnn个询问), 总移动的距离不超过nnn\sqrt nnn. 这是块内的情况,而左端点在块与块之间移动时,每次移动的距离不超过2n2\sqrt n2n, 但是由于只有n\sqrt nn个块,因此总移动次数不超过n\sqrt nn, 总距离O(n)O(n)O(n). 综上,左端点移动总距离O(nn)O(n\sqrt n)O(nn).
而右端点呢?更简单:对于左端点在同一个大小为n\sqrt nn的块内的询问,右端点是单调右移的,移动总距离不超过nnn, 又因为有n\sqrt nn个块,因此总距离O(nn)O(n\sqrt n)O(nn).
综上,左右端点移动的总距离为O(nn)O(n\sqrt n)O(nn), bzoj 5283这道题已经在O(nn)O(n\sqrt n)O(nn)的复杂度内解决,均摊每次询问O(n)O(\sqrt n)O(n).(然而bzoj老爷机毒瘤卡常呜呜呜…)

问题引入——三维莫队

刚才,我们处理的是一个二元函数S(x,y)S(x,y)S(x,y), 具有重要的转移性质。现在我们拓展这个问题,假设我们有一个三元函数f(x,y,z)f(x,y,z)f(x,y,z), 其可以在O(1)O(1)O(1)的时间内转移到f(x−1,y,z),f(x+1,y,z),f(x,y−1,z),f(x,y+1,z),f(x,y,z−1),f(x,y,z+1)f(x-1,y,z), f(x+1,y,z), f(x,y-1,z), f(x,y+1,z), f(x,y,z-1), f(x,y,z+1)f(x1,y,z),f(x+1,y,z),f(x,y1,z),f(x,y+1,z),f(x,y,z1),f(x,y,z+1)这六个值。有QQQ次询问,每次询问一个f(x,y,z)f(x,y,z)f(x,y,z)的值,x,y,z≤nx,y,z\le nx,y,zn, 是否可以较快速地求出所有询问的答案呢?
假设Q,n≤4.5×104Q, n\le 4.5\times 10^4Q,n4.5×104.

个人的想法

仿照二维莫队的思路,我们首先对询问进行排序。
瞎逼猜结论QAQ
注:性急的读者请跳过这一段推导,要读的请抱着批判的态度来读,读不懂或者有疑问请继续看下面,否则我概不负责!!!
一个(显然的)猜测是,既然二维莫队O(n12)O(n^\frac{1}{2})O(n21)每次,那我们三维的,是不是可以O(n23)O(n^\frac{2}{3})O(n32)每次呢? 对于询问f(x,y,z)f(x,y,z)f(x,y,z), 按照xn23\frac{x}{n^\frac{2}{3}}n32x为第一关键字,yn13\frac{y}{n^\frac{1}{3}}n31y为第二关键字,zzz为第三关键字排序,O(1)O(1)O(1)转移询问。
我们来复杂度分析(把大小为n23n^\frac{2}{3}n32的块称作大块,大小为n13n^\frac{1}{3}n31的块称作小块): 对于xxx每个大块内每次询问的移动距离是n23n^\frac{2}{3}n32, 总共nnn次询问,总移动距离O(n53)O(n^\frac{5}{3})O(n35).
对于yyy,当xxx在同一个大块内时,yyy的每次移动距离不超过n13n^\frac{1}{3}n31, 一共最多移动nnn次,总距离n43n^\frac{4}{3}n34, 对于xxx不在一个大块内,yyy的移动距离不超过nnn, 一共最多n13n^\frac{1}{3}n31次移动(因为就这么多个大块),总距离n43n^\frac{4}{3}n34. 综上,yyy的总移动距离O(n43)O(n^\frac{4}{3})O(n34).
对于zzz, 总移动距离就是O(x,y都不同的询问个数×n)O(x,y都不同的询问个数\times n)O(x,y×n). 而前者是O(n23)O(n^\frac{2}{3})O(n32),因此右端点总移动次数是…O(n53)O(n^\frac{5}{3})O(n35).
因此,总复杂度为O(n53)O(n^\frac{5}{3})O(n35), 每次询问均摊O(n23)O(n^\frac{2}{3})O(n32)


等等……这个是对的吗……
冷静思考一下:
对于zzz来说,如果我们按照刚才的方式把xxxyyy分成了若干类,那么这个类别的数目是多少呢?
xxxn13n^\frac{1}{3}n31类,yyyn23n^\frac{2}{3}n32类,那一共是……
相乘,nnn类!!
因此,刚才的分析是错误的,右端点总移动距离为O(n2)O(n^2)O(n2)
呜呜呜……又要重新推了……
算了,不想试数了,我们来形式化地推一发。
设我们的排序方式是第一关键字xna\frac{x}{n^a}nax, 第二关键字ynb\frac{y}{n^b}nby, 第三关键字zzz.
对于xxx, 在每个块内移动距离O(na)O(n^a)O(na), 总询问数O(n)O(n)O(n), 总距离O(n1+a)O(n^{1+a})O(n1+a).
对于yyy, 当xxx在同一大块内时,yyy每次移动距离O(nb)O(n^b)O(nb), 共nnn个询问,O(n1+b)O(n^{1+b})O(n1+b). 当xxx不在同一大块内时,有O(n1−a)O(n^{1-a})O(n1a)个大块,每个大块yyy要移动nnn的距离,因此O(n2−a)O(n^{2-a})O(n2a). 综上,yyy移动距离O(nmax⁡(1+b,2−a))O(n^{\max(1+b,2-a)})O(nmax(1+b,2a)).
对于zzz, 我们考虑x,yx,yx,y的块总共会将nnn个询问分成O(n1−a+1−b)O(n^{1-a+1-b})O(n1a+1b)类,对于每一类询问,都要移动nnn的距离,因此zzz移动距离O(n3−a−b)O(n^{3-a-b})O(n3ab).
然后我们来最优化。首先,为了让复杂度不至于达到O(n2)O(n^2)O(n2), 3−a−b3-a-b3ab必须&lt;2\lt 2<2, a+b&gt;1a+b\gt 1a+b>1. 而对于yyymax⁡(1+b,2−a)\max(1+b,2-a)max(1+b,2a), 1+b&gt;2−a1+b\gt 2-a1+b>2a等价于a+b&gt;1a+b\gt 1a+b>1, 因此恒满足,yyy的复杂度其实就是O(n1+b)O(n^{1+b})O(n1+b).
然后就简单了……O(n1+a),O(n1+b),O(n3−a−b)O(n^{1+a}), O(n^{1+b}), O(n^{3-a-b})O(n1+a),O(n1+b),O(n3ab), 平衡一下,显然a=b=n23a=b=n^\frac{2}{3}a=b=n32时取最优,O(n53)O(n^\frac{5}{3})O(n35), 单次均摊O(n23)O(n^\frac{2}{3})O(n32).

后记

重申,本人弱鸡,刚刚从bzoj 5283这道题里得到的启发,推了一发写了此文,若有错误敬请大佬们指出,感激不尽。
关于三维莫队问题,目前没有任何一个人跟我讨论过,纯粹是我自己的一点想法,也没有找其他人检验过(我好菜啊),也没有专门看过此类课题的论文,因此文章内容很可能有错误之处。不过刚才推了这么一大串,最后的核心思想就是一个,通过排序平衡三个端点的移动距离。刚才的内容如果正确,还可以推广到更高维的情况,但是更高维大概只有理论价值,实际上并不会比O(n2)O(n^2)O(n2)暴力快到哪里去。我相信,这个简简单单的问题早已被之前的大佬们解决,我只是发表一点自己的思考而已。如果哪位大佬在这个问题上有更优秀的做法,敬请指出,谢谢。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值