export declare class RangeLookup {
    private maxLevelSize;
    private buffer;
    private dataLength;
    /** When true, the lookup needs to be rebuilt before use */
    isDirty: boolean;
    constructor(allValues: number[][]);
    private static computeMaxLevelSize;
    private static createBuffer;
    private populateBuffer;
    /**
     * Rebuild the segment tree with new values, reusing the buffer if possible.
     * Only allocates a new buffer if the data length requires a different maxLevelSize.
     */
    rebuild(allValues: number[][]): void;
    /**
     * Update values at a specific data index - O(k log n) where k is number of columns.
     * After updating the leaf, propagates changes up to the root.
     *
     * @param dataIndex - Index in the data array (0-based)
     * @param newValues - New values for this index from all columns
     */
    updateValue(dataIndex: number, newValues: number[]): void;
    /**
     * Batch update multiple values - O(k log n) per update.
     * More efficient than individual updateValue calls when tracking dirty nodes.
     *
     * @param updates - Array of {index, values} pairs to update
     */
    updateValues(updates: Array<{
        index: number;
        values: number[];
    }>): void;
    /**
     * Propagate min/max changes from a leaf up to the root.
     * Each level recalculates its min/max from its children.
     */
    private propagateUp;
    private computeRangeInto;
    rangeBetween(start: number, end: number, into?: [number, number]): [number, number];
    getRange(into?: [number, number]): [number, number];
    get range(): [number, number];
    /** The number of data elements in the segment tree */
    get length(): number;
}
