No segment tree, using TreeSet to track Obstacles and TreeMap to track intervals
IntuitionTo determin whether we can place a block, we want to make sure there exists at least one interval (between 2 adjacent obstacles) which is larger or equ
# Intuition
To determin whether we can place a block, we want to make sure there exists at least one interval (between 2 adjacent obstacles) which is larger or equal to the block size.

How to find such interval? We need to keep track of the intervals when a obstacle is placed (i.e. query type 1).

# Approach
Use a TreeSet to store the obstacle locations, so that given a new obstacle to be placed, we can easily find out what is the previous and next obstacle (Log N time).

Use a TreeMap to store the "interval size -> a set of starting points of the interval", so that when placing a block, we can quickly find out the intervals that is >= block size, and iterate those starting points to check whether the block can be placed or not.


# Complexity
- Time complexity:
  - Place the obstacles (query 1): O(log n)
    Finding the previous and next locations: O(log n)
    Updating TreeMap (segMap): O(log m) for insertion and removal, where m is the number of intervals.
**Overall: O(log n + log m)**
  - Checking Block Placement (query 2)
    Finding the ceiling key in TreeMap (segMap): O(log m)
    Iterating through segments starting from the ceiling key: In the worst case, this could be O(m) but usually it's much less (say it's k)
    **Overall: O(log m + k) where k is number of intervals checked**


- Space complexity: O(N) where N is number of obstacles.
  - O(N) to store the obstacles
  - O(N) to store the intervals in TreeMap

# Code
```java []
import java.util.TreeSet;

class Solution {
    public List<Boolean> getResults(int[][] queries) {
        // a set of obstacle locations
        TreeSet<Integer> bars = new TreeSet<>();

        // interval length -> set of starting points
        TreeMap<Integer,Set<Integer>> segMap = new TreeMap<>();
        List<Boolean> res = new ArrayList<>();
        bars.add(0);
        bars.add(50001);

        for (int[] query : queries) {
            if (query[0] == 1) { // place the new obstacle (query type 1)
                int currLoc = query[1];
                bars.add(currLoc);
                int prevLoc = bars.lower(currLoc);
                int nextLoc = bars.higher(currLoc);
                int segLen = nextLoc - prevLoc;
                // find the existing interval and remove it, because after placing the new obstacle, the interval is splitted into 2. Thus need to remove the original one
                if (segMap.containsKey(segLen)) {
                    segMap.get(segLen).remove(prevLoc);
                    if (segMap.get(segLen).isEmpty()) {
                        segMap.remove(segLen);
                    }                    
                }
                // add 2 new intervals: prevLoc -> currLoc, currLoc -> nextLoc
                segMap.computeIfAbsent(currLoc - prevLoc, s -> new HashSet<>()).add(prevLoc);
                segMap.computeIfAbsent(nextLoc - currLoc, s -> new HashSet<>()).add(currLoc);
                
            } else { // block placement (query type 2)
                int blockLen = query[2];
                int upperLimit = query[1];
                // corner case
                if (blockLen > upperLimit) {
                    res.add(false);
                    continue;                    
                }

                // no intervals yet, thus definitely can place the block
                if (segMap.isEmpty()) {
                    res.add(true);
                    continue;
                }

                // No intervals that have size >= block size, can NOT place.
                Integer ceilingKey = segMap.ceilingKey(blockLen); 
                if (ceilingKey == null) {
                    res.add(false);
                    continue;
                }
                
                // Found a set of intervals that has size >= block size
                Set<Integer> eligibleKeys = segMap.tailMap(ceilingKey).keySet();

                // For these intervals, iterate the starting points, and determin whether can place the block or not.
                Boolean canPlace = false;
                for (Integer key : eligibleKeys) {
                    Set<Integer> startingLocs = segMap.get(key);
                    for (int starting : startingLocs) {
                        if (starting + blockLen <= upperLimit) {
                            canPlace = true;
                            break;
                        }
                    }
                    if (canPlace) break;
                }
                res.add(canPlace);
            }
        }

        return res;
    }
}
```
['Java']