关于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)算法,就要充分利用之前算出来的东西,稍想一下,有什么显而易见的性质可以用得上,

这个点的计算与它的前后计算有什么关系,对于每个点都有必要从头计算吗,等等。。。

持续更新、、、

   

原文地址:https://www.cnblogs.com/zyfzyf/p/3895487.html