c++分块算法(暴力数据结构)
快要noip了,该写些题解攒攒rp了(逃)
看到题解里那么多线段树啊,树状数组啊,本蒟蒻表示:这都是什么鬼东西?
在所有高级数据结构中,树状数组是码量最小的,跑的也基本是最快的,但理解很难,并且支持的操作很少;线段树的码量,相信写过线段树题的童鞋都亲身体验过这种恐怖(那些3min写完splay的巨佬不要d我),理解虽然简单,但一题调一辈子啊!
所以说到这里,本蒟蒻想表达什么呢?
分块大法吼啊!
有人会说:分块不是n√n的复杂度吗?怎么能跟nlogn的数据结构相提并论呢?或者说,分块在联赛中,有什么优势呢?
首先,虽然他复杂度高,但他能维护的东西多呀!(你看看n²的暴力什么不能维护)
而且,因为有时线段树有巨大的常数,反而比分块跑的慢!(比如洛谷P2801)
再者说,如果联赛一道题,好多方法都能做,你是用调一辈子的线段树呢,还是十分暴力好写的分块呢?
废话了这么多,也是想让大家知道,分块也是一种很好的算法。
那分块是怎么实现的呢?顾名思义,分块就是把一个区间分成好几个小区间,至于是几个呢,因题而异,但大部分题的复杂度都是n√n,所以默认是把区间分成√n块。如果某题用分块复杂度带log,就让块分的更多一些,大概是乘个log(我也不知道为什么)。
哪怎么维护呢?当询问某段区间时,把区间覆盖的整块打上一个tag标记,两边离散的块呢,就暴力就好了。有人会说,这么简单?当然。(不简单本蒟蒻怎么可能会写)
还有要注意的是询问区间如果在一个块里要特判,所以要多大几个if。(虽然有些麻烦,但都是板儿啊)
分块大体差不多说完了,但这个算法十分灵活,准确的说,分块这种思想十分可贵,能用到很多其他题上。
最后,如果想看分块的板子和拓展,hzwer大佬博客里有,可以去看一看(巨佬的码风是真好看啊)!
谢谢大家!