/** * data-structure-typed * * @author Pablo Zeng * @license MIT License */ export type SegmentTreeOptions = { merger: (a: E, b: E) => E; identity: E; }; /** * Generic Segment Tree with flat array internals. * * Supports any associative merge operation (sum, min, max, gcd, etc.). * Reference: AtCoder Library segtree. * * @example * ```ts * const sumTree = SegmentTree.sum([1, 2, 3, 4, 5]); * sumTree.query(1, 3); // 9 (2+3+4) * sumTree.update(2, 10); // [1, 2, 10, 4, 5] * sumTree.query(1, 3); // 16 (2+10+4) * * const minTree = SegmentTree.min([5, 2, 8, 1, 9]); * minTree.query(0, 4); // 1 * ``` */ export declare class SegmentTree implements Iterable { protected readonly _merger: (a: E, b: E) => E; protected readonly _identity: E; protected _n: number; protected _tree: E[]; protected _treeSize: number; constructor(elements: E[], options: SegmentTreeOptions); /** * Create a sum segment tree. * @example * ```ts * const st = SegmentTree.sum([1, 2, 3, 4, 5]); * st.query(0, 2); // 6 (1+2+3) * st.update(1, 10); * st.query(0, 2); // 14 (1+10+3) * ``` */ static sum(elements: number[]): SegmentTree; /** * Create a min segment tree. * @example * // Temperature monitoring with range queries * // Hourly temperatures for a day (24 readings) * const temps = [18, 17, 16, 15, 16, 18, 21, 24, 27, 29, 31, 32, 33, 32, 31, 29, 27, 25, 23, 21, 20, 19, 18, 17]; * const tree = SegmentTree.sum(temps); * * // Average temperature during work hours (9-17) * const workSum = tree.query(9, 17); * console.log(workSum / 9); // toBeCloseTo; * * // Sum of morning temps (6-11) * console.log(tree.query(6, 11)); // 164; */ static min(elements: number[]): SegmentTree; /** * Create a max segment tree. * @example * ```ts * const st = SegmentTree.max([3, 1, 4, 1, 5]); * st.query(1, 4); // 5 * ``` */ static max(elements: number[]): SegmentTree; /** * Point update: set element at index to value. * Time: O(log n) * @example * // Dynamic range sum with updates * // Monthly revenue data (in thousands) * const revenue = [120, 95, 140, 110, 85, 130, 150, 100, 160, 125, 90, 175]; * const tree = SegmentTree.sum(revenue); * * // Q1 revenue (Jan-Mar) * console.log(tree.query(0, 2)); // 355; * * // Update March revenue from 140 to 200 * tree.update(2, 200); * * // Q1 revenue after update * console.log(tree.query(0, 2)); // 415; * * // H1 revenue (Jan-Jun) * console.log(tree.query(0, 5)); // 740; */ update(index: number, value: E): void; /** * Range query: returns merger result over [start, end] (inclusive). * Time: O(log n) * @example * // Range sum query on an array * const tree = SegmentTree.sum([1, 3, 5, 7, 9, 11]); * * // Query sum of range [1, 3] → 3 + 5 + 7 = 15 * console.log(tree.query(1, 3)); // 15; * * // Query entire range * console.log(tree.query(0, 5)); // 36; * * // Query single element * console.log(tree.query(2, 2)); // 5; */ query(start: number, end: number): E; /** * Get element at index. * Time: O(1) * @example * // Point access on segment tree * const st = SegmentTree.sum([10, 20, 30, 40]); * console.log(st.get(0)); // 10; * console.log(st.get(2)); // 30; */ get(index: number): E; /** * Find the largest r such that predicate(query(left, r)) is true. * Returns left-1 if predicate(identity) is false. * Returns n-1 if predicate holds for the entire range [left, n-1]. * Time: O(log n) * @example * // Find rightmost position where predicate holds * // Prefix sums: find the rightmost index where prefix sum < 10 * const st = SegmentTree.sum([3, 1, 4, 1, 5]); * // maxRight(0, sum => sum < 10) — prefix [3,4,8,9,14] * // sum < 10 holds through index 3 (prefix=9), fails at 4 (prefix=14) * const result = st.maxRight(0, sum => sum < 10); * console.log(result); // 3; */ maxRight(left: number, predicate: (segValue: E) => boolean): number; /** * Find the smallest l such that predicate(query(l, right)) is true. * Returns right+1 if predicate(identity) is false. * Returns 0 if predicate holds for the entire range [0, right]. * Time: O(log n) * @example * // Find leftmost position where predicate holds * const st = SegmentTree.sum([3, 1, 4, 1, 5]); * // minLeft(5, sum => sum < 7) — suffix sums from right * // From right: [5]=5 < 7, [1,5]=6 < 7, [4,1,5]=10 ≥ 7 * const result = st.minLeft(5, sum => sum < 7); * console.log(result); // 3; */ minLeft(right: number, predicate: (segValue: E) => boolean): number; get size(): number; isEmpty(): boolean; clone(): SegmentTree; toArray(): E[]; /** * Iterates over leaf values in index order. */ [Symbol.iterator](): IterableIterator; forEach(callback: (value: E, index: number) => void): void; print(): void; }