The log2 function call can be slow. Precompute for all lengths:
LOG = [0] * (n + 1)
for i in range(2, n + 1):
LOG[i] = LOG[i // 2] + 1
``` Now `LOG[len]` gives $\lfloor \log_2(len) \rfloor$ in $O(1)$.
Query becomes:
```pseudocode
def query(l, r):
k = LOG[r - l + 1]
return min(st[l][k], st[r - (1 << k) + 1][k])
``` Each query runs in $O(1)$ with no function calls. Just array lookups and bit shifts. Time: $O(1)$. Space: $O(n \log n)$.