别的不说,上来一句分块你🐎死了(当我没说)
众所周知分块是一种优秀暴力的数据结构思想那你还写了五天。
基本思想就是将一个大的区间分成几个小块,分别暴力维护小块中的信息,求解时再暴力合并怎么说了全是暴力啊。
好吧我们先考虑一个问题:
有一个长度为n的整数数列a。
现在有m个操作,操作的格式有两种:
1 x y,表示修改,将数列第x个数a[x]改为a[x]+y;
2 x y, 表示询问,询问第x个数到第y个数间,最大的一个数是多少。
这不是线段树裸题吗
但是用分块常数小更暴力好写啊qwq。
先直接暴力:每次修改 O ( 1 ) O(1) O(1),每次查询 O ( n ) O(n) O(n) 的做法是个人都会。
然后我们使用分块可以让暴力稍微好看一点:将区间分成 S S S 块,分别维护这些块中的最大值。
接下来考虑两种操作:
u p d a t e update update 操作(将数列第 x x x 个数 a x a_x ax 改为 a x + y a_x+y ax+y):修改后在它所属的块种暴力重新统计最大值。
q u e r y query query 操作:先查询 x x x 和 y y y 之间的块,统计这些块的最大值,然后对于两边的不完整区间直接暴力统计。
每个下标 x x x 在第 ( x − 1 ) / S + 1 (x-1)/S+1 (x−1)/S+1 块中。
u p d a t e update update 复杂度: O ( S ) O(S) O(S)
q u e r y query query 复杂度: O ( S + n / S ) O(S+n/S) O(S+n/S)
根据均值不等式,块长 S S S 取 n \sqrt{n} n 最佳
所以:
u p d a t e update update 复杂度: O ( n ) O(\sqrt{n}) O(n)
q u e r y query query 复杂度: O ( n ) O(\sqrt{n}) O(n