算法 之 ST表
文章目录
- 区间最大值
ST
表(Sparse Table
)是一种高效处理静态数据区间查询
的数据结构,主要的作用是用于快速查询区间的最值,区间GCD,区间按位与或
在这里以区间最大值为例子说明st表的模版
- 总体的思想就是定义
dp[i][j]
表示下标为i长度为2^j的区间的最大值
,这个dp
数组的定义的大小第一维度为原始的数组的长度(+1也可以),第二个维度就是数组长度取log2然后+1,反正就是得取大点
初始化st表
def init_st(n)
# 假设数组的下标从1开始
for i in range(1,N):
dp[i][0] = num[i]
# 枚举区间的长度,假设最大的长度不超过2^19
for i in range(1,20):
# 枚举区间的开始的位置,原始的下标的范围是 1到 n
# 区间长度为2^i的时候,区间的最右边的下标最大可以为n-(1<<i)+1
for j in range(1,n-(1<<i)+2):
# 分为两部分,后面的那一半的开始位置是 j + 2^(i-1)
dp[j][i] = max(dp[j][i-1],dp[j+(1<<(i-1))][i-1])
查询操作
def query_st(l,r):
k = int(math.log2(r-l+1))
return max(dp[l][k],dp[r-(1<<k)+1][k])
区间最大值
区间最大值
- 直接套用模版
import math
# 直接使用st表进行求解
N,Q = map(int,input().split())
a = [0] + list(map(int,input().split()))
dp = [[0]*(20) for _ in range(N+1) ]
def init_stl():
# 初始化st表
# 定义dp[i][j]表示以i开始的,长度为2^j的区间的最大值
for i in range(1,N+1):
dp[i][0] = a[i]
# 枚举长度的幂次
for i in range(1,20):
# 枚举开始的位置
for j in range(1,N-(1<<i)+2):
dp[j][i] = max(dp[j][i-1],dp[j+(1<<(i-1))][i-1])
def query_stl(l,r):
k = int(math.log2(r-l+1))
ans = max(dp[l][k],dp[r-(1<<k)+1][k])
return ans
init_stl()
for _ in range(Q):
l,r = map(int,input().split())
print(query_stl(l,r))