ST表问题

写在前面

  • 在写题时我们常常会遇见 R M Q RMQ RMQ问题(区间最值),那么对于求解 R M Q RMQ RMQ问题,我们有多种解法,如线段树,单调队列等等,现在我要讲的是一种倍增解法即 S T ST ST算法。

ST讲解

  • 给定一段序列 A A A S T ST ST算法能在 O ( N l o g N ) O(NlogN) O(NlogN)的时间预处理后,以 O ( 1 ) O(1) O(1)的复杂度查询,在线回答在一段区间 l , r l, r l,r中最大(小)值是多少。
  • 对于一段序列,我们可以选取一些 2 2 2的整数次幂来作为代表值从而划分整个区域。
  • F [ i , j ] F[i, j] F[i,j]表示序列 A A A在子区间 [ i , i + 2 j − 1 ] [i, i + 2^j-1] [i,i+2j1]内取得的最大值,那么显然一段区间的最大值等于它左右段子区间的最大值中的最大值,即 F [ i ] [ j ] = m a x ( F [ i ] [ j − 1 ] , F [ i + 2 j − 1 − 1 ] [ j − 1 ] ) F[i][j] = max( F[i][j-1], F[i + 2^{j-1} - 1][j - 1]) F[i][j]=max(F[i][j1],F[i+2j11][j1])
  • 递推边界为 F [ i , 0 ] = A [ i ] F[i,0] = A[i] F[i,0]=A[i]
  • 当我们查询的时候延用刚才的思路,一个区间的最大值等于它两个左右子区间的最大值。询问区间 [ l , r ] [l,r] [l,r]时,我们选出一个数 t t t,满足 2 t &lt; r − l + 1 ⩽ 2 t + 1 2^t &lt;r-l+1 \leqslant 2^{t+1} 2t<rl+12t+1,那么从 l l l开始的 2 t 2^t 2t个数到以 r r r结尾的 2 t 2^t 2t个数,一定覆盖整个区间 [ l , r ] [l,r] [l,r],这两段区间的最大值分别为 F [ l , t ] F[l,t] F[l,t] F [ r − 2 k + 1 , t ] F[r-2^k+1,t] F[r2k+1,t],取最大值即可。

代码实现

预处理

void ST_prework() {
	for (int i = 1; i <= n; ++i) f[i][0] = a[i];
	for (int j = 1; j <= 20; ++j) {
		for (int i = 1; i <= n - (1 << j) + 1; ++i) {
			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]);
} 

例题

luogu P2251
在求解过程中把 m a x max max,改成 m i n min min即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值