分块
按字面意思来看,分块就是把一个序列分成若干块来处理,维护好每一块信息
对于给定的数据规模n,预设一个块的大小s,然后从左到右前s个视为第一块,第s+1块到2s个元素视为第2块,以此类推(最后一块不够s个,可以忽略这个问题)
刚开始的时候可以默认s=sqrt(n)这样的话块的大小和个数都是O(sqrt(n))
分块的本质还是分治,类似于线段树,但是线段树每次从区间中间劈开两半,而分块是第一层按照s个划一刀的方式分开
有很多的问题不支持快速归并,所以线段树就坏掉了;比如:找区间众数的出现次数
所以这个算法就不能使用线段树了
考虑将序列分为s=sqrt(n)块,然后处理一个ans[l,r]表示从l到r块的答案(所以在做题我们要学会一种思想,假设思想,也就是设方程未知数的思想)
具体的方法就是枚举l,从第l块左端点开始枚举i,用一个cnt数组维护第l块左端点到i的区间众数,
O(sqrt(n))修改 O(1)查询
仍然使用分块的思想,维护s[i]表示前i块的数字之和,有点像前缀和
每次修改的时候只要把所在块和之后的块s修改一下即可
询问的时候仍然可以通过差分整块的答案,然后部分使用暴力
莫队
他只能进行离线查询,时间复杂度O(n sqrt(m))