莫队算法

本文深入讲解了莫队算法的不同变种,包括普通莫队、带修莫队、树上不带修莫队和树上带修莫队。详细分析了算法的时间复杂度,并提供了实例问题链接,帮助读者理解算法的应用。

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

普通莫队

按照左端点所在块为第一关键字,右端点为第二关键字排序。然后按照暴力做即可。

B B B表示块的大小, n n n表示序列长度, m m m表示询问数,时间复杂度分析:

  1. 左端点 l l l移动次数最多是 询问数 * 块大小: O ( m B ) O(mB) O(mB)
  2. 右端点 r r r移动次数最多是 块个数 * 总长 O ( n 2 B ) O(\frac{n^2}{B}) O(Bn2)

于是这个的时间复杂度为 O ( m B + n 2 B ) O(mB+\frac{n^2}{B}) O(mB+Bn2).

根据基本不等式可得这个对勾函数当 B = n m B=\frac{n}{\sqrt{m}} B=m n时时间复杂度最小,为 O ( n m ) O(n\sqrt{m}) O(nm ),总时间复杂加上排序就是 O ( n m + m l o g m ) O(n\sqrt{m}+mlogm) O(nm +mlogm)

应用

百度即可。

带修莫队

经典例题:https://jzoj.net/senior/#main/show/4594

核心思想是把版本嵌套在普通莫队上,每次要注意版本对区间的影响

即先更新当前版本对当前区间的影响,如果版本往前,那么查看是否会对当前区间有影响,有影响则更新,版本往后同理。

最后再跟普通莫队一样,在当前版本上进行左右断点的移动。

排序的方式是:以 n 2 3 n^{\frac{2}{3}} n32为一块,一共将序列分为 n 1 3 n^{\frac{1}{3}} n31块。排序第一关键字是左端点所在块编号,第二关键字是右端点所在块编号,第三关键字是对应版本。

模板类似:

for (int i = 1; i <= m; i ++) {
        while (K < q[i].k) Change(++ K);
        while (K > q[i].k) Change(K --);
        while (R < q[i].r) Add(++ R);
        while (L > q[i].l) Add(-- L);
        while (R > q[i].r) Del(R --);
        while (L < q[i].l) Del(L ++);
        res[q[i].pos] = ans;
}

时间复杂度分析(与上面相同 B B B表示块大小,且假设 n , m n,m n,m同阶):

  1. 版本移动:最多有 ( n B ) 2 {(\frac{n}{B})}^2 (Bn)2 r r r块,对于每个 r r r块 版本最多移动 n n n次,所以复杂度是 O ( n 3 / B 2 ) O(n^3/B^2) O(n3/B2).
  2. 右端点 r r r移动:由于移动递增,所以 r r r块相同时,最多移动 B B B次,时间复杂度是 O ( m B ) O(mB) O(mB) r r r块不同时,由于只有 n / B n/B n/B l l l块,所以最多移动 n 2 B \frac{n^2}{B} Bn2次,总的复杂度是 O ( m B + n 2 B ) O(mB+\frac{n^2}{B}) O(mB+Bn2).
  3. 左端点 l l l移动:每次最多移动 B B B个,时间复杂度是 O ( m B ) O(mB) O(mB)

n , m n,m n,m同阶时复杂度为 O ( n B + n 2 B + n 3 B 2 ) O(nB+\frac{n^2}{B}+\frac{n^3}{B^2}) O(nB+Bn2+B2n3),设 B = n x ∣ ( 0 &lt; x &lt; 1 ) B=n^x|(0\lt x\lt 1) B=nx(0<x<1),那么复杂度可以写成 n max ⁡ ( x + 1 , 2 − x , 3 − 2 x ) n^{\max(x+1,2-x,3-2x)} nmax(x+1,2x,32x),易知 x = 2 3 x=\frac{2}{3} x=32时时间复杂度最小,为 O ( n 5 3 ) O(n^{\frac{5}{3}}) O(n35).

树上不带修莫队

一般解决树上路径问题。

这个有一种很好的解决办法,即利用括号序。

对于一段路径 x , y x,y x,y,如果其 l c a lca lca不是它们中一点,则可以把路径对应到原序列上

序列中 x x x右括号位置到 y y y左括号位置中出现一次的点,再加上 x x x y y y l c a lca lca

否则假设 y y y l c a lca lca,那么可以对应到原序列上

序列中 y y y左括号位置到 x x x左括号位置中出现一次的点

这样就转化为普通莫队了。

树上带修莫队

根据前两个知识即可。

例题:BZOJ3052: [wc2013]糖果公园

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在 IT 领域,文档格式转换是常见需求,尤其在处理多种文件类型时。本文将聚焦于利用 Java 技术栈,尤其是 Apache POI 和 iTextPDF 库,实现 doc、xls(涵盖 Excel 2003 及 Excel 2007+)以及 txt、图片等格式文件向 PDF 的转换,并实现在线浏览功能。 先从 Apache POI 说起,它是一个强大的 Java 库,专注于处理 Microsoft Office 格式文件,比如 doc 和 xls。Apache POI 提供了 HSSF 和 XSSF 两个 API,其中 HSSF 用于读写老版本的 BIFF8 格式(Excel 97-2003),XSSF 则针对新的 XML 格式(Excel 2007+)。这两个 API 均具备读取和写入工作表、单元格、公式、样式等功能。读取 Excel 文件时,可通过创建 HSSFWorkbook 或 XSSFWorkbook 对象来打开相应格式的文件,进而遍历工作簿中的每个 Sheet,获取行和列数据。写入 Excel 文件时,创建新的 Workbook 对象,添加 Sheet、Row 和 Cell,即可构建新 Excel 文件。 再看 iTextPDF,它是一个用于生成和修改 PDF 文档的 Java 库,拥有丰富的 API。创建 PDF 文档时,借助 Document 对象,可定义页面尺寸、边距等属性来定制 PDF 外观。添加内容方面,可使用 Paragraph、List、Table 等元素将文本、列表和表格加入 PDF,图片可通过 Image 类加载插入。iTextPDF 支持多种字体和样式,可设置文本颜色、大小、样式等。此外,iTextPDF 的 TextRenderer 类能将 HTML、
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值