分块学习笔记

—分块是一个暴力优化算法,可以通过暴力优化来保证时间复杂度 (较好的暴力)

(现在才学也是没谁了qwq)

算法实现

假设有一道题目,要求支持区间修改,区间查询,相信大家都会用线段树或树状数组求解,但是,如果题目要求一段区间内修改后权值为 k k k 的个数呢?

肥肠难办呢~~

让我们回归最初的暴力,暴力枚举区间的范围,暴力加减,然后再暴力枚举求解答案(太暴力了),分块就是在这个基础上优化时间复杂度的。

1.修改

假设我们将这段序列分为很多段,那么如果这个区间完全被包含在需要更改的区间内,只需要给这整一个大块打上一个 t a g tag tag 标记,表示这一个大块内元素一起被加上(减少)多少。
那不完整的块呢?只需要暴力枚举元素强行将初始值更改即可。

2.查询

题目中要求区间查询和权值为 k k k 的个数。

区间查询很好办,只需要记录一个 s u m sum sum 表示一个整块的初始值的和,那么一个整块的贡献为初始值和 + + + t a g ∗ tag * tag 区间元素个数。同样,对于不完整的块,暴力枚举元素,加入其权值以及 t a g tag tag 值即可。

查询权值为 k k k 的个数有点难办。。
我们如果使得每一个块都是有序的,那么我们就可以用二分快速求出答案。
很明显,我们可以对于每一个块都排一边序,强行使它有序,二分出最靠右的 k k k 和最靠右的 k − 1 k-1 k1 ,就可以求出块内的贡献啦!
同样,不完整的块直接暴力求解,更新答案即可

时间复杂度

很明显,只要分的块数为 n \sqrt n n ,那么时间复杂度是最优的。

修改的时间复杂度:
对于完整的块,最多有 n \sqrt n n 块,所以时间复杂度为 O ( n n ) O(n \sqrt n) O(nn )
对于不完整的块,最多有 2 n 2 \sqrt n 2n 个元素(假设左边右边全塞满了),时间复杂度也是 O ( n n ) O(n \sqrt n) Onn 的。

区间查询的时间复杂度:
同修改的一样,也是 O ( n n ) O(n \sqrt n) O(nn ) 的。

查询权值为 k k k 的个数的时间复杂度:
排序是 ( n l o g n ) (\sqrt n log \sqrt n) (n logn ) 的(最多有 n \sqrt n n 个块嘛)。 ,二分查找也是 O ( n l o g n ) O(\sqrt n log \sqrt n) O(n logn ) 的。
而暴力枚举部分是 O ( n ) O(\sqrt n) O(n ) 的 。

所以总的时间复杂度为 O ( n n l o g n ) O(n \sqrt n log \sqrt n) O(nn logn ) 的,比普通的暴力好上不少呢!
总之,分块还是一个十分不错的算法。

当然,分块的进阶版——莫队,还得有分块的前置知识才行~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值