倍增就是字面意思,成倍的增长,如果状态空间很大,通常的线性递推无法满足要求时,那么我们可以采用成倍增长的方式,只递推状态空间中在2的整数次幂位置上的值作为代表。而其他位置的值我们可以通过“任意整数可以表示成若干个2的次幂项的和”这一性质,使用之前求出的代表值拼成所需的值。所以使用倍增算法也要求我们问题的状态空间关于2的次幂具有可划分行。
倍增和二进制划分相结合,降低了求解问题的时间和空间复杂度。
1. ST算法
在RMQ(区间最值问题)问题中,著名的ST算法就是倍增的产物。给定一个长度问N的数列A,ST算法可以在$O(Nlog 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]); }