ST表

ST表

稀疏表(SparseTable)

概述

ST 表基于 倍增 思想,可以做到\(O(nlog_2n)\) 预处理, \(O(1)\) 回答每个询问。

用于处理可重复贡献问题的区间查询!

可重复贡献问题

重叠并不会对区间计算的值产生影响!

区间最值、区间按位和、区间按位、区间GCD

题目链接

https://www.luogu.com.cn/problem/P3865

模板

from math import log2
import sys
input = lambda:sys.stdin.readline()

# 静 态 查 询 区 间 最 值

# N = int(1e3 + 5)
# M = int(log2(N) + 1)
n,m = map(int,input().split())

N = n + 10
M = int(log2(N)) + 1
a = [0] + [*map(int,input().split())]

# st[i][j] 表 示 以 i 开 始,长 度 为 2^j 的 区 间 的 值 !
st = [[0 for _ in range(M)] for _ in range(N)]

for i in range(1,n + 1):
    st[i][0] = a[i]

# 预 处 理 区 间 信 息
for j in range(1,M):
    for i in range(1,n + 1):
        length = 1 << (j - 1)
        if i + length <= n:
            # 区间长度为:2^j     left:[i,i + 2^(j - 1) - 1]   right:[i + 2^(j - 1),i + 2^(j - 1) + 2^(j - 1) - 1]
            left,right = st[i][j - 1],st[i + length][j - 1]
            st[i][j] = max(left,right)
        else:
            break


# 查 询 [l,r] 区 间 的 最 值
def query(l,r):
    k = int(log2(r - l + 1))
    # 区间长度为 2^k   left:[l,l + 2^k - 1]   right:[r - 2^k + 1,r]
    left,right = st[l][k],st[r - (1 << k) + 1][k]
    return max(left,right)

# 一 下 子 全 输 出 更 快 !
ans = [0] * m
for i in range(m):
    l,r = map(int,input().split())
    ans[i] = query(l,r)
print(*ans,sep='\n')
posted @ 2024-03-25 12:48  gebeng  阅读(18)  评论(0)    收藏  举报