// Construct new range-min query index. // // The data argument is stored on the index. Modifying its contents may // invalidate the range-min index's results. // // Takes O(n log n) time where n = data.Len(). func New(data Interface) *Index { // Sparse table DP algorithm from Bender et al.: // https://www3.cs.stonybrook.edu/~bender/pub/JALG05-daglca.pdf (§2.3) n := data.Len() if n == 0 { panic("data.Len() must be > 0") } logn := intmath.Log2(n) t := newTable(n, logn) // Base case: unit length ranges. for i := 0; i < n; i++ { t.set(i, 0, i) } for j := uint(1); (1 << j) <= n; j++ { for i := 0; i+int(1<<j)-1 < n; i++ { l := t.at(i, j-1) r := t.at(i+int(1<<(j-1)), j-1) if data.Less(l, r) { t.set(i, j, l) } else { t.set(i, j, r) } } } return &Index{Data: data, n: n, table: t} }
// Returns the index of the minimum of r.Data[i:j]. Takes constant time. // // The index is relative to the start of r.Data. Ties are broken in an // arbitrary way. // // i >= j is a runtime error. func (r *Index) Min(i, j int) int { switch { case i >= j: panic("got i >= j in Index.Min") case j > r.n: panic("j > data.Len() in Index.Min") case i+1 == j: return i } k := uint(intmath.Log2(j - i)) a := r.at(i, k) b := r.at(j-int(1<<k), k) if r.Data.Less(a, b) { return a } return b }
// Strings sorts a slice of strings in increasing order (byte-wise // lexicographically). // // This function is equivalent to sort.Strings, but faster than the // implementation in Go 1.4. func Strings(a []string) { n := len(a) radixQuicksort(a, 0, 0, n, 2*intmath.Log2(n+1)) }