Editorial for IOI '04 P1 - Artemis
Submitting an official solution before solving the problem yourself is a bannable offence.
Observation: Let be the number of trees below and to the left of . Then the number of the trees in the rectangle bounded by and is:
if lies below and to the left of (or vice versa), and a similar formula if not.
Trivial algorithm. Loop over all rectangles, and loop over all trees to count those inside the rectangle.
Use dynamic programming to compute for every . Then evaluate all rectangles using the formulae.
, but also memory
Place an outer loop over the trees, representing one corner of a potential rectangle. To evaluate rectangles with corners at , one only needs and . These can be computed with DP as in algorithm (2), and requires only linear memory.
Sort the trees from left to right, and then process them in that order. As each new tree (say ) is added, it is inserted into a list of current trees that is sorted vertically. From this information one can calculate and for every to the left of , in linear time. Then one can evaluate all rectangles with one corner at . This ends up being very similar to algorithm (3).
Algorithm (1), but with optimised counting. As a pre-process, associate a bitfield with each tree representing which trees lie below and to the right, and a similar bitfield for trees below and to the left. The trees inside a given rectangle may be found as the binary AND of two bitfields. A fast counting mechanism (such as a 16-bit lookup table) will accelerate counting.
and memory, but with low constant factors
Comments