关于O(n)算法
首先要明确一点,当数据规模达到百万时需用O(n)算法
如何实现O(n)算法,其实是对原有算法的一种改进
后者说是 原有算法+一点小性质=O(n)算法
下面我将举几个例子来说明这一点:
1.后缀数组中height数组的求法,暴力算法hash+二分
用上height[rank[i]]>=height[rank[i-1]]-1可以做到O(n)
2.NOI2014动物园
原算法:从每个点一直while往回跳,直到满足条件,最坏情况下O(n^2)
新算法:利用一个显然的性质,一个前缀的 f 值不可能大于它的后继的 f 值
从未考虑到建立一棵树,对叶节点暴力跳,对非叶节点让它的 f 初始值为后继中 f 最小的那个
我们只要从根节点 dfs 一次就可以了
(ps:ms也可能会被卡?不过实测中效果还是蛮不错的)
3.CH Round #45 能量释放
原算法:单调队列算出每个点管辖的范围,再用一次rmq,复杂度O(nlogn)
新算法:利用性质:如果 j 被 i管辖,那么 j 管辖的范围 i 也一定都能管辖
从而考虑 对数列顺着、逆着各扫一遍
从左到右时,计算l[i] 首先令j=i-1 如果j 被 i 管辖,就j=l[j]-1,同时更新这个点的ans,直到不能跳,复杂度不好估计
............
总的来说,如何构造出O(n)算法,就要充分利用之前算出来的东西,稍想一下,有什么显而易见的性质可以用得上,
这个点的计算与它的前后计算有什么关系,对于每个点都有必要从头计算吗,等等。。。
持续更新、、、