Editorial for IOI '04 P1 - Artemis


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Observation: Let f(x,y) be the number of trees below and to the left of (x,y). Then the number of the trees in the rectangle bounded by t1 and t2 is:

f(t1.x,t1.y)+f(t2.x,t2.y)f(t1.x,t2.y)f(t1.y,t2.x)+1

if t1 lies below and to the left of t2 (or vice versa), and a similar formula if not.

  1. Trivial algorithm. Loop over all rectangles, and loop over all trees to count those inside the rectangle.

    O(n3)

  2. Use dynamic programming to compute f(t1.x,t2.y) for every t1,t2. Then evaluate all rectangles using the formulae.

    O(n2), but also O(n2) memory

  3. Place an outer loop t over the trees, representing one corner of a potential rectangle. To evaluate rectangles with corners at t, one only needs f(t.x,) and f(,t.y). These can be computed with DP as in algorithm (2), and requires only linear memory.

    O(n2)

  4. Sort the trees from left to right, and then process them in that order. As each new tree (say tn) is added, it is inserted into a list of current trees that is sorted vertically. From this information one can calculate f(t.x,tn.y) and f(tn.x,t.y) for every t to the left of tn, in linear time. Then one can evaluate all rectangles with one corner at tn. This ends up being very similar to algorithm (3).

    O(n2)

  5. 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.

    O(n3) and O(n2) memory, but with low constant factors


Comments

There are no comments at the moment.