For Problem 2, preprocess blocks of the same type (height, width) into an array of x-coordinates. For each block with coordinates (x, y), insert x into the array at index y.
For the query part, go through each block type (there are only 22 types) and, for each type, consider every y-coordinate that might contain the query point (at most 128 values/the block height). For each valid y-coordinate, perform a binary search to find the largest x-coordinate that is less than or equal to the query's x-coordinate . If it exist, check if the block at that location contains the query point.
This is like O(22 * 128 * log(frameWidth)) and might only be worth it if frameHeight can be very big