# 读入
n, m = map(int, input().split())
a = list(map(int, input().split()))
# 预处理 log2 值:log[i] = floor(log2(i)),i >= 1
log = [0] * (n + 1)
for i in range(2, n + 1):
log[i] = log[i // 2] + 1
# 构建 ST 表
k_max = log[n] + 1 if n > 0 else 1
st = [[0] * k_max for _ in range(n)]
# 初始化 j=0
for i in range(n):
st[i][0] = a[i]
# 填表
for j in range(1, k_max):
span = 1 << j # 区间长度 = 2^j
for i in range(n - span + 1):
st[i][j] = max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1])
# ===== 打印 log 数组 =====
print("log 数组(log[i] = floor(log2(i)),用于 RMQ 查询):")
print("i: ", end="")
for i in range(n + 1):
print(f"{i:>3}", end="")
print()
print("log[i]:", end="")
for i in range(n + 1):
print(f"{log[i]:>3}", end="")
print("\n")
# ===== 打印 ST 表 =====
print("ST 表 (st[i][j] = 从下标 i 开始、长度为 2^j 的区间最大值):")
if n == 0:
print("(空数组)")
else:
# 表头
header = "i \\ j |" + "".join(f"{j:>6}" for j in range(k_max))
print(header)
print("-" * len(header))
# 每一行
for i in range(n):
row = f"{i:>5} |"
for j in range(k_max):
if i + (1 << j) <= n: # 区间 [i, i + 2^j) 不越界
row += f"{st[i][j]:>6}"
else:
row += " " # 留空
print(row)
# 如果还有查询,可以继续处理(本题暂不执行查询,只展示结构)
输入数据
输入样例
10 2
3 2 4 5 6 8 1 2 9 7
1 4 //查询索引从1到4的最大值
3 8 //查询索引从3到8的最大值
输出样例
5
8
结果如下:
log 数组(log[i] = floor(log2(i)),用于 RMQ 查询):
i: 0 1 2 3 4 5 6 7 8 9 10
log[i]: 0 0 1 1 2 2 2 2 3 3 3
ST 表 (st[i][j] = 从下标 i 开始、长度为 2^j 的区间最大值):
i \ j | 0 1 2 3
--------------------------------
0 | 3 3 5 8
1 | 2 4 6 9
2 | 4 5 8 9
3 | 5 6 8
4 | 6 8 8
5 | 8 8 9
6 | 1 2 9
7 | 2 9
8 | 9 9
9 | 7
图片:
—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com