st表操作(附代码)

概念

我们用 st[i][j] 来表示原数组 a[n] 中区间 [ i , i + 2 j − 1 ] [i, i + 2^j - 1] [i,i+2j1] 内的最大值, 以实现用 O(1) 的复杂度来查询任意区间 [p, q] 的最大值, 具体怎么实现看下文。

初始化

我们对 st[i][0] 进行初始化

for (int i = 1; i <= n; i++)
	st[i][0] = a[i];

进一步初始化(构造st表)

int p = log(n)/log(2);
for (int j = 1; j<= p; j++)
	for(int i = 1; i + (1 << j) - 1 <= n; i++)
		st[i][j] = max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);

查询

int query(int p, int q) {
	int k = log(q - p + 1)/log(2);
	return max(st[p][k], st[q - (1 << k) + 1][q]);
}

完整代码

// 建表复杂度 nlogn, 查询复杂度 1
#include <iostream>
#include <cmath>
#define MAXN 100
using namespace std;
struct ST{
    int f[MAXN][MAXN];
    void build(int a[], int n){
        for (int i = 1; i <= n; i++)
            f[i][0] = a[i];
        int k = log(n) / log(2);
        for (int j = 1; j <= k; j++)
            for (int i = 1; i + (1 << j) - 1 <= n; i++)
                f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
    }
    int query(int l, int r){
        int q = log(r - l + 1) / log(2);
        return max(f[l][q], f[r - (1 << q) + 1][q]);
    }
};
int main(){
    int a[11] = {0, 5, 3, 7, 2, 12, 1, 6, 4, 8, 15};
    ST st1;
    st1.build(a, 10);
    cout << st1.f[3][3] << endl;
    cout << st1.query(2, 8) << endl;
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值