LOJ 数列分块入门 1-9

可能是一句话题解。单独发布于博客园。

LOJ-6277 数列分块入门 1

块长 \(\sqrt{n}\)。修改时对于整块打标记 \(tag\),对于两边的零散块单独修改。询问时的答案是其本身的答案加上其所在块的标记值。

AC code.

LOJ-6278 数列分块入门 2

考虑计算小于 \(c^2\) 的人数用二分,但是必须满足块内有序。区间加一个整块是不会导致块内复杂度变化的。只需要单独处理两边的零散块,即区间加之后将其块排序。只是不要忘了处理的时候加上 \(tag\),因为区间加仍然需要 \(tag\) 维护。

AC code.

LOJ-6279 数列分块入门 3

和上面那道题差不多。对于整块,还是二分找小于一个数的最大的数,零散块单独找。

AC code.

LOJ-6280 数列分块入门 4

这才是最正宗的模板题。

考虑对于整块除了 \(tag\) 多记录和 \(ans\),当然还需要有每个元素的值 \(a_i\)。修改时对于零散块直接修改 \(a\)\(ans\),对于整块修改 \(tag\)。询问时对于零散块中的每个元素加上其 \(a_i\) 和其块的 \(tag_x\),对于整块加上其 \(ans_i\) 和其 \(tag_i\times siz_i\)。因为里面的每一个元素都加上了 \(tag_i\),而总共有 \(siz_i\) 个元素。

AC code.

LOJ-6281 数列分块入门 5

发现就算是 \(2^{31}-1\),最多开方 \(6\) 次后也会变成 \(1\)。而 \(1\) 开方永远都是 \(1\),会一直循环。所以一整个区间最多开方 \(6\) 次所有元素都会变成 \(0/1\),而无论后面怎么操作都不会改变了。那么用 \(tag\) 记录这个整块内是不是只剩下 \(0/1\) 了,如果不是就将这个整块暴力开方。这样做不会超时,因为暴力开方的次数并不多。零散块处理同理。

AC code.

LOJ-6282 数列分块入门 6

这是分块重构的 trick。

随机数据的话可以暴力插入。这里考虑假设不是随机数据的情况。标解里面有这样一句话:

如果先在一个块有大量单点插入,这个块的大小会大大超过 \(\sqrt{n}\),那块内的暴力就没有复杂度保证了。

我们要避免这种情况的发生。如果我们发现一个块的长度过长,那么就应当重新构建分块(即将分块重新分组)。这样可以保证每次的操作复杂度尽量均衡。那么如何判定“长度过长”呢?标解给出的解法是如果一个块的长度超过了初始时块的长度的 \(20\) 倍就重新构建。

AC code.

LOJ-6283 数列分块入门 7

仍然是模板题。多打一个乘法标记 \(mul\) 即可。可以类比洛谷上「线段树 1」和「线段树 2」的区别,需要注意作乘法操作的时候加法标记和乘法标记 \(add,mul\) 都要乘。

AC code.

LOJ-6284 数列分块入门 8

类似分块入门 4,可以直接对于每个块打上该块内元素是否一样的标记。是的话标记值为该块内所有元素的值(都是一样的),否则为 \(\text{inf}\)。操作时对于零散块暴力维护并更新其标记。对于整块则有:

  • 如果该块标记不为 \(\text{inf}\),则表示其内部是同一种颜色
    • 如果 \(tag\neq val\),那么该块内所有元素都不是 \(val\)\(ans\) 不变,\(tag\) 更改为 \(val\)
    • 如果 \(tag=val\),那么该块内所有元素都是 \(val\)\(ans\) 加上该块长度。
  • 否则:
    暴力维护该块,操作与修改零散块类似。

需要注意的是,上面的做法貌似看上去是 \(\mathcal{O(n^2)}\) 的。原因是暴力维护整块看上去并不优秀。但是,根据均摊的思想,一个块一次暴力推平的复杂度是 \(\mathcal{O(\sqrt{n})}\),但是此后的询问操作复杂度降为 \(\mathcal{O(1)}\)。而每次操作最多让两个零散块的 \(tag\to \text{inf}\),所以想要有一次暴力推平,要先花费 \(\sqrt{n}\) 的操作修改。均摊下来的复杂度就是 \(\mathcal{O(n\sqrt{n})}\)。(可能讲的不清楚,感性理解qwq。)

AC code.

LOJ-6285 数列分块入门 9

最后一道题。首先离散化。然后考虑预处理两个数组 \(s_{i,j}\) 表示前 \(i\) 个块内 \(j\) 的个数,\(p_{i,j}\) 表示第 \([i,j]\) 块内的众数,这些都很好维护。然后考虑处理询问,设 \(x,y\) 的在的块分别为 \(tx,ty\)

  • \(ty-tx\leq 1\),则它们中间不包含整块。暴力求众数。
  • \(ty-tx\geq 2\),则他们中间包含整块。这次显然不可能用暴力求了。但是我们发现只有两边零散块里面的元素和中间整块里面的 \(p_{tx+1,ty-1}\) 有可能成为最后的众数。那些存在于整块之中(不是 \(p_{tx+1,ty-1}\))而没有在零散块中出现的元素不可能比 \(p_{tx+1,ty-1}\) 优,不用考虑。这下就可以暴力比较了。(\(s\) 数组用来辅助计算个数。)

AC code.

完结撒花。

posted @ 2025-07-25 17:30  xuchuhan  阅读(21)  评论(0)    收藏  举报