ST算法介绍
ST 表是用于解决 可重复贡献问题 的数据结构

ST算法,能在 O(nlogn)时间的预处理后,以O(1)的时间复杂度在线回答"数列A中下标在l~r之间的数的最大值是多少"这样的区间最值问题

// dp[i][j]表示数列在[i, i + 2 ^ j - 1]里的最大值// 初始状态是 dp[i][0] = a[i]// 递推公式 dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1])void ST_prework(){ for (int i = 1; i <= n; i++) dp[i][0] = a[i]; int Log = (int)(log(1.0 * n) / log(2.0)) + 1; for (int j = 1; j < Log; j++) for (int i = 1; i <= n - (1 << j) + 1; i++) dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);}

询问时,先计算出使得2^k 小于区间长度,且最大那么,就可以用 "从l开始的2^k个数" 和 "以r结尾的2^k个数",这两段覆盖整个区间[l, r]即使有重叠也没关系int ST_query(int l, int r){ int k = (int)(log(1.0 * (r - l + 1)) / log(2.0)); return max(dp[l][k], dp[r - (1 << k) + 1][k]);}
关于log的预处理
1、使用cmath的log函数,执行效率很高,影响不大。需要注意的是,参数和返回值都是doubledouble log (double x);2、手动预处理int Log[N]; // 预处理logLog[1] = 0;for (int i = 2; i <= n; i++) Log[i] = Log[i >> 1] + 1;
ST算法特点
ST 表能较好的维护“可重复贡献”的区间信息(同时也应满足结合律),时间复杂度较低,代码量相对其他算法很小。但是,ST 表能维护的信息非常有限,不能较好地扩展,并且不支持修改操作
例题