首页 > 其他分享 >「学习笔记」分块

「学习笔记」分块

时间:2023-01-01 21:11:58浏览次数:55  
标签:frac 分块 复杂度 笔记 学习 完整 块长 ldots

树状数组、线段树、ST 表……这些数据结构我们用的也不算少了,但实际上这些数据结构还不够灵活,面对一些区间问题时反而会出问题。

举个栗子:

现在有 \(n\) 个单调队列需要维护,将要进行 \(m\) 次操作,操作有两种:
1、给编号在 \([l,r]\) 的单调队列插入一个数字 \(x\);
2、将编号为 \(x\) 的单调队列尾部的元素删除并插入编号为 \(y\) 的单调队列。

(PS:相信有些人还不知道单调队列是什么,他们应该认真读完 这篇文章

很显然,上述数据结构完全无法维护我提到的这个问题(虽然我接下来要说的思想也不一定能解决)

所以,神通广大的 OIer 研究出了 分块 的思想。

分块的基本思想是,通过对原数据的适当划分,并在划分后的每一个块上预处理部分信息,从而较一般的暴力算法取得更优的时间复杂度。

而分块的时间复杂度则主要取决于块长,一般来说最优时间复杂度下的块长是可以通过下面的公式求出来的。

\[\sqrt[n]{\prod_{i=1}^n x_i}\le \frac{\sum_{i=1}^n x_i}{n} \]

以上不等式取等号时,会满足 \(\prod_{i=1}^n x_i\) 最大或 \(\sum_{i=1}^n x_i\) 最小。

这就是 基本不等式(和高中课本上的不一样)。

但一般情况下,块长取 \(\sqrt n\) 就可以达到比较好的复杂度了。

分块思想非常灵活,下面讲一道例题。

给定长度为 \(n(1\le n\le 10^5)\) 序列 \(A\),有两个操作:
1、令 \(A_l,A_{l+1},\cdots,A_r\) 加上 \(x\);
2、求 \(\sum_{i=l}^r A_i\)。

我们将序列按每 \(s\) 个元素一块进行分块,并记录每块的区间和 \(b_i\)。

\[\underbrace{a_1, a_2, \ldots, a_s}_{b_1}, \underbrace{a_{s+1}, \ldots, a_{2 s}}_{b_2}, \ldots, \underbrace{a_{(s-1) \times s+1}, \ldots, a_n}_{b \frac{n}{s}} \]

最后一个块可能是不完整的(因为 \(s\) 很可能不是 \(n\) 的倍数),但是这对于我们的讨论来说并没有太大影响。

首先看查询操作:

  • 若 \(l\) 和 \(r\) 在同一个块内,直接暴力求和即可,因为块长为 \(s\),因此最坏复杂度为 \(O(s)\)。
  • 若 \(l\) 和 \(r\) 不在同一个块内,则答案由三部分组成:以 \(l\) 开头的不完整块,中间几个完整块,以 \(r\) 结尾的不完整块。对于不完整的块,仍然采用上面暴力计算的方法,对于完整块,则直接利用已经求出的 \(b_i\) 求和即可。这种情况下,最坏复杂度为 \(O(\frac{n}{s}+s)\)。

接下来是修改操作:

  • 若 \(l\) 和 \(r\) 在同一个块内,直接暴力修改即可,因为块长为 \(s\),因此最坏复杂度为 \(O(s)\)。
  • 若 \(l\) 和 \(r\) 不在同一个块内,则需要修改三部分:以 \(l\) 开头的不完整块,中间几个完整块,以 \(r\) 结尾的不完整块。对于不完整的块,仍然是暴力修改每个元素的值(别忘了更新区间和 ),对于完整块,则直接修改 \(b_i\) 即可。这种情况下,最坏复杂度和仍然为 \(O(\frac{n}{s}+n)\)。

利用基本不等式可知,当 \(\frac{n}{s}=s\),即 \(s=\sqrt{n}\) 时,单次操作的时间复杂度最优,为 \(O(\sqrt{n})\)。

标签:frac,分块,复杂度,笔记,学习,完整,块长,ldots
From: https://www.cnblogs.com/cantorsort2919/p/17018536.html

相关文章

  • 理财课程学习
    王喆老师的个人专栏:https://www.zhihu.com/column/c_1329728387019952128“在你没法在10万这个级别建立稳健的投资组合的时候,贸然用更多的钱参与投资,只会因为进退失据获......
  • 朱刘算法学习笔记
    一句话概括:朱刘算法就是最小生成树算法在有向图中的应用。树形图:无环除了根以外,每个点的入度为1最小树形图:一个有向图,存在从某个点开始的到达所有的的一个最小......
  • 文件包含学习笔记
    文件包含原理include()include_once()require()require_once()include()和require()的区别:require()如果在包含过程中出错,就会直接退出,不执行后续语句include(......
  • AC自动机学习笔记
    一句话概括:\(AC\)自动机\(=Trie+Kmp\)算法复习\(Trie\)字典树,顾名思义,是一个字典一样的树,结构非常简单,不再赘述。codeintson[N][26],cnt[N],idx;voidinser......
  • 2-SAT学习笔记
    \(SAT:satisfaction\)\(SAT\)问题:若干问题\(x_1,x_2,...,x_n\),另有\(m\)个需要满足条件,其中每个命题为真或假,求\(x_1,x_2,...,x_n\)的一种取值。一般\(k-SAT\)问......
  • 我的第一天学习-HelloWorld详解
    HelloWorld详解1.随便新建一个文件夹存放代码2.新建一个Java文件文件后缀名为.javaHello.java[注意]系统可能没有显示文件后缀名,需要我们手动打开,在文件查看中......
  • 狂神说Java(零基础)预科班笔记
    前言​以下笔记是根据B站up主遇见狂神说的Java零基础学习视频整理而成,视频链接点这里跳转(狂神说系列Java零基础版)。由于本人推崇费曼学习法,不想要写完一篇笔记之后就直......
  • 动手深度学习系列笔记
    动手学深度学习在线课程此系列文章为听课所敲代码+笔记,使用jupyternotebook展现目录​​3月20日​​​​3月21日​​​​3月27日​​​​3月28日​​​​4月10日​​​​4......
  • 【树模型与集成学习】(task6)梯度提升树GBDT+LR
    学习总结(1)不同问题的提升树学习算法,主要区别在于使用的损失函数不同,如用平方误差损失函数的回归问题、用指数损失函数的分类问题、用一般损失函数的一般决策问题等。(2)不管......
  • 操作系统OS笔记目录(清华大学)
    简介不得不说想自学学操作系统,清华大学慕课是个不错的选择,但难度比较大,特别是想把慕课的实验部分内容也完成的话。不过如果能把它的实验部分也完成的话,相信你会对操作系统......