Problem Description
Given an infinite number line starting at 0 (extending only along the positive x‑axis), you are asked to handle two types of queries:
- For a query of type 1, given as [1, x], build (place) an obstacle at position x. It is guaranteed that there is no obstacle at x when this query is issued.
- For a query of type 2, given as [2, x, sz], determine if it is possible to place a block of length sz anywhere in the interval [0, x] such that the block (which may touch but not intersect any obstacle) lies completely in [0, x].
Return a boolean array corresponding to the type 2 queries where each entry is true if it is possible to place such a block, and false otherwise.
Key Insights
- Placing obstacles on the number line splits [0, x] into free intervals.
- A block of length sz can be placed if at least one free interval (or a truncated free interval at the boundary x) has length at least sz.
- Using a segment tree that “remembers” the longest contiguous free segment is a great way to support both dynamic updates (when an obstacle is added) and range queries (to check for a large enough free interval).
- In the segment tree, each node will store: • prefix length: the contiguous free segment starting at the left end, • suffix length: the contiguous free segment ending at the right end, • best: the maximum free contiguous interval within the segment, • total: the length (number of positions) of the segment.
- For an update (type 1 query), we mark the position as blocked (i.e. “0”) and update the tree.
- For a query (type 2), we query the segment tree for the range [0, x] and check if the “best” free length is at least sz.
Space and Time Complexity
Time Complexity:
- Update (placing an obstacle): O(log M) per update, where M is the maximum possible position (here, M ≤ 50000).
- Query (checking free interval): O(log M) per query.
Space Complexity: O(M) to store the segment tree.
Solution
We solve the problem by modeling the positions [0, M] (with M equal to the maximum x encountered in the queries) in a segment tree. Initially, all positions are free. Each leaf node of the segment tree represents a single position, and its values (prefix, suffix, best) are initialized to 1. When an obstacle is placed at a position x, we update that leaf to 0 (blocked). The segment tree nodes merge their children’s values so that each node accurately reflects: • prefix: if the entire left child is free, then the free length extends into the right child’s prefix, • suffix: similarly using the right child, • best: the larger of the left child’s best, the right child’s best, or a combination of the left child’s suffix and the right child’s prefix. For a query, we fetch the node information for the interval [0, x] and check if the best free contiguous segment length is at least sz.