分块&势能分析!!!(orz Flash!)

挂个博客表示自己还活着
之后会弄系统总结这个就当是preview好了

分块

数列分块入门九题(hzwer)

  • 入门题1,2,3,4,5,7

问题:给一段区间打上标记后单点查询

解法:主要是每块维护一些标记,计算答案等,此类分块较为简单

注意:块大小一般为\(\sqrt n\)

复杂度:\(O(n\sqrt n)\)

  • 入门题6

问题:每次朝数列中间插入一个元素,查询第k个元素是什么

解法:块大小超过一定值后暴力重构!采用链表实现$**

复杂度:\(O(n\sqrt n)\)

  • 入门题8

问题:每次询问一个区间内为\(c​\)的元素个数,并把整个区间改为\(c​\)

解法:维护一个区间覆盖标记,如果块内没有标记就暴力修改

注意:复杂度分析要用到FlashHu的势能分析

势能(potential energy)是储存于一个系统内的能量,也可以释放或者转化为其他形式的能量。

把一个块搅乱,相当于给其增加\(O(\sqrt n)\)的势能,表示其再次被打上全局tag所需要的代价

每次操作最多把两个块搅乱,所以每次操作最多增加\(O(2\sqrt n)\)的势能,同时整理好一个块需要的代价是其势能,并能把其势能降为\(O(1)\)

这样子最多搅乱\(n\)个块,增加\(O(2n\sqrt n)\)的势能,最多把他们所有的势能都变成\(1\),复杂度为\(O(4n\sqrt n)=O(n\sqrt n)\)

理解:增加势能需要相应代价,减少势能也需要相应代价,对应分析其最大势能即可得出复杂度

拓展:分析每次可以从栈中弹出多个元素的复杂度(还是\(O(n)\),其总势能最大为\(O(n)\)

  • 入门题9

问题:在线维护区间最小众数

解法:离线就可以用莫队搞了

考虑分块,分块是一个很好的算法,维护每个数在数列中的前缀和是\(O(n^2)\)的时空复杂度,但是给分个块就可以做到\(O(n\sqrt n)\)

一段区间的众数一定属于:A.零散块内的数 B.整块内的众数,一共数量不超过\(\sqrt n\)

所以维护两个数组:\(f[i][j]\)表示从第\(i\)块到第\(j\)块的众数,这个可以\(O(\sqrt n\sqrt n\sqrt n)\)的预处理出来;\(g[i][j]\)表示离散化后的数字\(i\)在前\(j\)块中出现的次数,这个可以\(O(n)\)赋值后\(O(n\sqrt n)\)统计前缀和而得到

之后便只需要:A.统计每个数在整块内的出现个数\(O(1×\sqrt n)\) B.统计零散块中的数\(O(\sqrt n)\)

综上,复杂度为\(O(n\sqrt n)\),完美通过此题/蒲公英

猜你喜欢

转载自www.cnblogs.com/xzyxzy/p/9691929.html