ยง Sparse table

// mins [l, l+1) = arr[l]
for(int i = 0; i < n; ++i) { mins[i][0] = arr[l]; }
for(int len = 1; len < NBITS; ++len) {
  for(int i = 0; i < n; ++i) {
    const int midix = i + 1 << (len-1);
    if (midix >= n) { break; }
    // mins [l..l+N) = min mins[l..l+N/2) mins[l+N/2..l+N]
    mins[i][l] = min(mins[i][len-1], mins[i + midix][len-1]);
  }
}
    [--------------)
1 2 3 4 5 6 7 8 9 10
    |       |   |  |
    [-------)   |  |
            [---)  |
                [--)
    [-----------)
1 2 3 4 5 6 7 8 9
    |     | |   |
    [-----+-)   |
          [-----)
The actual expression is:
// [l, r)
int query_mins(int l, int r) {
  int len = r-l;
  if (len < 0) { return INFTY; }
  int j = log2(len); // round down.
  // min  [l, l+halflen), [l+halflen, r)
   return min(mins[l][j], mins[l+-(1<<j)][j]);
}