def _build_index(self):
row0 = list(map(len, self._lists))<EOL>if len(row0) == <NUM_LIT:1>:<EOL><INDENT>self._index[:] = row0<EOL>self._offset = <NUM_LIT:0><EOL>return<EOL><DEDENT>head = iter(row0)<EOL>tail = iter(head)<EOL>row1 = list(starmap(add, zip(head, tail)))<EOL>if len(row0) & <NUM_LIT:1>:<EOL><INDENT>row1.append(row0[-<NUM_LIT:1>])<EOL><DEDENT>if len(row1) == <NUM_LIT:1>:<EOL><INDENT>self._index[:] = row1 + row0<EOL>self._offset = <NUM_LIT:1><EOL>return<EOL><DEDENT>size = <NUM_LIT:2> ** (int(log_e(len(row1) - <NUM_LIT:1>, <NUM_LIT:2>)) + <NUM_LIT:1>)<EOL>row1.extend(repeat(<NUM_LIT:0>, size - len(row1)))<EOL>tree = [row0, row1]<EOL>while len(tree[-<NUM_LIT:1>]) > <NUM_LIT:1>:<EOL><INDENT>head = iter(tree[-<NUM_LIT:1>])<EOL>tail = iter(head)<EOL>row = list(starmap(add, zip(head, tail)))<EOL>tree.append(row)<EOL><DEDENT>reduce(iadd, reversed(tree), self._index)<EOL>self._offset = size * <NUM_LIT:2> - <NUM_LIT:1><EOL>
Build an index for indexing the sorted list.

        Indexes are represented as binary trees in a dense array notation
        similar to a binary heap.

        For example, given a _lists representation storing integers:

        [0]: 1 2 3
        [1]: 4 5
        [2]: 6 7 8 9
        [3]: 10 11 12 13 14

        The first transformation maps the sub-lists by their length. The
        first row of the index is the length of the sub-lists.

        [0]: 3 2 4 5

        Each row after that is the sum of consecutive pairs of the previous row:

        [1]: 5 9
        [2]: 14

        Finally, the index is built by concatenating these lists together:

        _index = 14 5 9 3 2 4 5

        An offset storing the start of the first row is also stored:

        _offset = 3

        When built, the index can be used for efficient indexing into the list.
        See the comment and notes on self._pos for details.