import { StopId } from '../stops/stops.js';
import { Time } from '../timetable/time.js';
import type { IRaptorState } from './raptor.js';
import { RoutingEdge, RoutingState } from './state.js';
/**
 * RAPTOR state for Range RAPTOR mode, implementing {@link IRaptorState}.
 *
 * Holds both the cross-run shared labels (carried over from one departure-time
 * iteration to the next, latest → earliest) and a reference to the current
 * per-iteration {@link RoutingState} (swapped via {@link setCurrentRun}).
 *
 * Concretely, `roundLabels[k][p]` is the best known arrival at stop `p` using
 * at most `k` transit legs, across **all departure times tried so far**.
 *
 * @see https://www.microsoft.com/en-us/research/wp-content/uploads/2012/01/raptor_alenex.pdf
 */
export declare class RangeRaptorState implements IRaptorState {
    /**
     * `roundLabels[k]` is a flat `Uint16Array` of size `nbStops`.
     * `roundLabels[k][p]` = best arrival time (minutes from midnight) at stop `p`
     * in round `k`, across all departure-time iterations processed so far.
     * Pre-filled with `UNREACHED_TIME`; updated in-place as better arrivals are found.
     */
    readonly roundLabels: Uint16Array[];
    /**
     * The latest departure time of the range query.
     */
    readonly latestDeparture: Time;
    /**
     * Global best arrival at any destination stop across all runs and rounds.
     * Used for destination-pruning inside scan methods so that routes that cannot
     * beat the already-known best are skipped early.
     */
    private _destinationBest;
    /**
     * Sparse change-tracking for `initRound`.
     *
     * `changedInRound[k]` is the list of stops whose round-k label was improved
     * (via `tryImprove`) since the last call to `initRound(k + 1)`.  When
     * `initRound(k + 1)` runs, it only visits these stops instead of scanning
     * all `nbStops` entries, reducing the work from O(nbStops × rounds ×
     * departureTimes) to O(changedStops × rounds × departureTimes).
     *
     * Duplicates are allowed and harmless — a stop that appears twice merely
     * receives a redundant (no-op) min-update on the second visit.  The list is
     * cleared inside `initRound` immediately after processing.
     */
    private readonly changedInRound;
    private currentRun;
    constructor(maxRounds: number, nbStops: number, latestDeparture: Time);
    /**
     * Swaps in a fresh {@link RoutingState} for the next departure-time iteration
     * and seeds the shared round-0 labels from its access arrivals.
     *
     * Must be called before every `runRaptor` invocation.
     */
    setCurrentRun(routingState: RoutingState): void;
    get origins(): StopId[];
    get graph(): (RoutingEdge | undefined)[][];
    arrivalTime(stop: StopId): Time;
    /**
     * Uses the cross-run shared label for `round`, which is always at least as
     * tight as the per-run arrival and therefore provides stronger pruning.
     */
    improvementBound(round: number, stop: StopId): Time;
    /**
     * Global best arrival at any destination across all departure-time iterations.
     * Always at least as tight as the per-run `destinationBest`.
     */
    get destinationBest(): Time;
    get maxArrivalTime(): Time;
    isDestination(stop: StopId): boolean;
    /** Updates the per-run aggregate best when improved, and always considers the cross-run shared label. */
    updateArrival(stop: StopId, time: Time, round: number): void;
    /**
     * initialized round `k` from round `k-1`: τk(p) ← min(τk(p), τk-1(p)).
     *
     * Must be called at the very start of each RAPTOR round before routes are
     * scanned.  After this call, `roundLabels[k][p]` is the minimum arrival at
     * stop `p` achievable with **at most** k transit legs from any departure time
     * tried so far — which is exactly the tightest valid pruning bound for round k.
     */
    initRound(round: number): void;
}
