The solution is easiest to up with by considering the 1-dimensional case i.e., a 1-dimensional table (size
) with incremental updates and queries on sums of values on an interval. If the values on the table are stored as such, computing the sum of an interval requires
operations. A query of the sum of values stored on a certain interval
can also be answered by computing the cumulative sums
and
and then the answer
. The sums
and
can be stored in the table, in which case the query can be answered in
. Maintaining the sums then causes the update to require
operations.
Figure 3. A binary indexed tree with the update structure of the tree in solid lines and a dashed line presenting the path of a query of the sum of the interval
![[1, 7]](//static.dmoj.ca/mathoid/30a80a9af80fc01a0b48ba89514cba67a7781404/svg)
(

). Only the rows marked with the tree level need to be stored.
The binary indexed tree data structure (Figure 3) presented in [1] can support cumulative sum computation and update in
and only takes the same space as the raw table. In the tree the indices run from
and each cell at index
contains the sum of an interval
where
is the number of trailing zeroes in the binary representation of the index of the cell. Thus the sum of an interval can be computed with 2
queries. The next cell in an update can be computed by adding to the current index value its lowest 1 bit. Similarly in a query, the next cell index can be obtained by subtracting the lowest 1-bit. An update requires updating all the cells that contain the sum of an interval containing the cell, this can also be done in
operations. The computation of sums can be made a little faster for small intervals by noting that the cumulative sum queries will eventually hit the same cells and stop at the first common cell (the query ends up adding and subtracting the same cell).
The solution to the 1-dimensional case can be generalized to any number of dimensions (in the case of the IOI competition 2D, i.e., an
table). The trees are placed using the same logic as in the 1-dimensional case forming a tree of trees. In this case, the tree-like structure of the cell at coordinate
contains the sum of an area which is determined by the number of zeroes in the binary representation of
in the X-direction and respectively the number of zeroes in the binary representation of
in the Y-direction. The structure can then support queries of a sum of values in the rectangle
in time
(for a
-dimensional case
). The query for a rectangular shape can be expressed in terms of these basic queries (e.g. 4 queries in the 2-dimensional case:
![\displaystyle sum([L, R] \times [B, T]) = sum([1, R] \times [1, T]) - sum([1, L-1] \times [1, T]) - sum([1, R] \times [1, B-1]) + sum([1, L-1] \times [1, B-1]))](//static.dmoj.ca/mathoid/1d2cf0ba93c2a2fd0d1eab753c9c36d6775548ce/svg)
(See Figure 4 for examples.) The example solution also optimizes this for small queries using the same method as the 1-dimensional case. The task also requires indexing to start at
and the binary indexed tree data structure requires indexing that starts at
.
Figure 4. Update and query paths in the 2-dimensional solution from left to right: update

, update

,
![sum([1, 7] \times [1, 7])](//static.dmoj.ca/mathoid/83855721ab72a6d690d7d685ee368f48ad9cdf8c/svg)
,
![sum([1, 6] \times [1, 3])](//static.dmoj.ca/mathoid/9b3b0b67d90e7ac06cdbd7699f5253f1ad762776/svg)
.
Examples are shown in Figure 5.
Figure 5. Illustration of some sums of areas stored in different cells, the storing cell is black, the area stored (including the cell) is dark gray.
It is also possible to order the area sums in other ways, in which case the indexing scheme changes.
Reference
[1] P. M. Fenwick, A new data structure for cumulative frequency tables, Software - Practice and Experience 24, 3 (1994), 327-336, 1994
Comments