1.6 倍增

  倍增就是字面意思,成倍的增长,如果状态空间很大,通常的线性递推无法满足要求时,那么我们可以采用成倍增长的方式,只递推状态空间中在2的整数次幂位置上的值作为代表。而其他位置的值我们可以通过“任意整数可以表示成若干个2的次幂项的和”这一性质,使用之前求出的代表值拼成所需的值。所以使用倍增算法也要求我们问题的状态空间关于2的次幂具有可划分行。

  倍增和二进制划分相结合,降低了求解问题的时间和空间复杂度。

1. ST算法

  在RMQ(区间最值问题)问题中,著名的ST算法就是倍增的产物。给定一个长度问N的数列A,ST算法可以在$O(N\log N)时间的预处理后,以O(1)$的时间复杂度在线回答”数列A中下标在l~r之间的数的最大值是多少“这样的区间最值问题。

void ST_process(){
    for(int i = 0; i <= n; ++i) f[i][0] = a[i];

    for(int i = 0; i <= n; ++i)
        for(int j = 1; i + 1 << j <= n; ++j)
            f[i][j] = max(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
}

int ST_query(int l, int r){
    int t = log(r - l + 1) / log(2);
    return max(f[l][t], f[r - (1 << t) + 1][t]);
}

  

 

相关练习:

1. Genius ACM

posted @ 2019-10-10 16:52  楓羽  阅读(179)  评论(0编辑  收藏  举报