SparseTable
1. Sparse Table
(1) 概要
数列(リスト)に対して,指定区間における最小値/最大値等の演算を求めるクエリにO(1)で解答するためのデータ構造
データ構造の作成には,O(NlogN)必要
前提:数が不変(変化する場合は,セグメント木を使う)
可能な演算例:最小値,最大値,最大公約数,最小公倍数
不可能な演算例:四則演算
(2) 実装例(コンテスト問題未検証)
code:python
# 区間最小値.参考ページを基に,numpyが使えない環境でも動作するように変更
class SparseTable:
def __init__(self, a):
n = len(a)
max_k = n.bit_length() - 1 # 幅が2^0, 2^1, 2^2, ..., 2^{max_k}の区間を作る
INF = float('inf')
table = [INF * n for _ in range(max_k + 1)] # tableki: 幅2^kのi番目の区間における最小値 table0 = a # 幅1の区間の最小値は,元の値そのもの last_width = 1
for k in range(1, max_k + 1):
width = 1 << k # 区間幅
for i in range(n - width + 1):
# 現在の区間の最小値 = min(区間の前半分の最小値,区間の後半分の最小値)
last_width = width
self.table = table
def query(self, l, r):
""" min value of l, r """ width = r - l + 1 # 区間幅
if width == 1:
k = width.bit_length() - 1
width = 1 << k # tableで使用する区間幅.区間幅を超えない最大の2のべき乗
# 左端から幅2^kを取った区間と,右端から幅2^kを取った区間の最小値
st = SparseTable(a)
print(st.query(0, 2)) # a0~a2の最小値 ... 1 print(st.query(1, 3)) # a1~a3の最小値 ... 4 print(st.query(1, 6)) # a1~a6の最小値 ... 2 print(st.query(6, 6)) # a6~a6の最小値 ... 3