<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Faster Average Case Low Memory Semi-External Construction of the Burrows-Wheeler Transform</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>German Tischler⇤</string-name>
          <email>german.tischler@sanger.ac.uk</email>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>The Wellcome Trust Sanger Institute, Wellcome Trust Genome Campus Hinxton</institution>
          ,
          <addr-line>Cambridge, CB10 1SA</addr-line>
          ,
          <country country="UK">United Kingdom</country>
        </aff>
      </contrib-group>
      <fpage>61</fpage>
      <lpage>68</lpage>
      <abstract>
        <p>The Burrows Wheeler transform has applications in data compression as well as full text indexing. Despite its important applications and various existing algorithmic approaches the construction of the transform for large data sets is still challenging. In this paper we present a new semi external memory algorithm capable of constructing the transform in time O(n log2 log n) on average if sucient internal memory is available to hold a fixed fraction of the input text. In the worst case the run-time is O(n log n log log n).</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>-</title>
      <p>
        The Burrows-Wheeler transform (BWT) was introduced to facilitate the lossless
compression of data (cf. [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ]). It has an intrinsic connection to some data structures
used for full text indexing like the sux array (cf. [
        <xref ref-type="bibr" rid="ref11">11</xref>
        ]) and is at the heart of some
compressed full text self indexes like the FM index (see [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ]). The FM index requires
no more space than the k’th order entropy compressed input text plus some
asymptotically negligible supporting data structures. Many construction algorithms for
the BWT are based on its relation to the sux array, which can be computed from
the input text in time linear in the length of that text (see e.g. [
        <xref ref-type="bibr" rid="ref10 ref13">10, 13</xref>
        ]). While
these algorithms run in linear time and are thus theoretically optimal they require
O(n log n)1 bits of space for the uncompressed sux array given an input text of
Copyright c by the paper’s authors. Copying permitted only for private and academic purposes.
⇤ Supported by the Wellcome Trust
1 by log we mean log2 in this paper
length n while the text itself can be stored in a space of ndlog e bits for an alphabet
of size where we often have ⌧ n and in most applications is constant.
Algorithms for computing the sux array in external memory have been proposed (see
e.g. [
        <xref ref-type="bibr" rid="ref2 ref5">2, 5</xref>
        ]) but these algorithms require large amounts of space and input/output in
external memory. An asymptotically optimal internal memory solution concerning
time and space has been proposed [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ]. However the space usage of this algorithm
is O(n) bits for constant alphabets, where an inspection of the algorithm suggests
that the actual practical memory usage of the algorithm is several times the size of
the text in bits. The practical space usage of the algorithm subsequently presented
in [
        <xref ref-type="bibr" rid="ref14">14</xref>
        ] is lower (i.e. the involved constants are smaller) while theoretically not
linear. It however still requires multiple times as much space as the input text. A
sample implementation given by the authors only works for input sizes of up to
232 (see [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ]) and only handles a single level of the recursive algorithm. Given the
implementation complexity of the algorithm it remains unclear if it would scale
well. Crochemore et al present an algorithm computing the BWT in quadratic
time with constant additional space (see [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ]). In [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] Beller et al propose a semi
external algorithm for the construction of the BWT based on induced sorting. An
algorithm is called semi external if it uses non negligible amounts of internal as well
as external memory. According to the authors the algorithm scales to arbitrary
input sizes and uses about one byte (i.e. 8 bits) per input symbol in internal
memory. An algorithm constructing the BWT of a text by block-wise merging using a
finite amount of internal memory is presented in [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ]. The algorithm partitions the
text into a set of fixed size blocks. The run-time is O(n2/b) for a block size of b
and a text length of n. It requires an amount of internal memory which is roughly
sucient to compute the sux array of a single of these block. In particular the
amount of internal memory used can be smaller than the space required for the
text. In this paper we modify this algorithm to run in time O(n log n log log n) in
the worst case and O(n log2 log n) on average for the case where we are able to
keep a fixed fraction of the text in memory. Assuming the practically common
case of a finite alphabet the algorithm in [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ] uses blocks of size O(n/ log n) blocks
when provided with O(n) bits of space in internal memory so its total run-time for
this setting is O(n log n). In consequence our algorithm is faster on average and
slower by O(log log n) for a very unlikely worst case. Compared to the algorithm
presented in [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] our algorithm can work with less internal memory. For DNA for
instance the complete text can be held in memory using about 2 bits per symbol
which is significantly less than a full byte (8 bits) per character.
2
      </p>
      <p>Definitions
For a string s = s0s1s2 . . . sm 1 of length |s| = m we define s[i] = si for 0  i &lt; m
and for s = s0s1 . . . we define s[i] = si for 0  i. For a finite word u and a finite or
infinite word v we write their concatenation as uv. For any finite words u, x and
finite or infinite words w, v such that w = uxv we call u a prefix, v a sux and x a
factor of w. The empty word consisting of no symbols is denoted by ✏. For a string
s and indices 0  i  j &lt; |s| we denote the factor s[i]s[i + 1] . . . s[j] by s[i, j]. For
any i, j such that i &gt; j the term s[i, j] denotes the empty word. A finite word w
has period p i↵ w[i] = w[i + p] for i = 0, . . . , |w| p 1 and an infinite word w
has period p i↵ w[i] = w[i + p] for i = 0, 1, . . .. For a finite word u and k 2 N the
k’th power uk of u is defined by u0 = ✏ and ui+1 = uiu for i 2 N. A word w is
primitive if it is not a power of a word u such that |u| &lt; |w|. A word u is a root of
w if w = uk for some k 2 N. A word w is a square if there is a word u such that
w = u2. Throughout this paper let ⌃ = {0, 1, . . . , 1} denote a finite alphabet
for some &gt; 0 and let t = t0t1 . . . tn 1 2 ⌃ n denote a finite string of length n &gt; 0.
We define the semi infinite string t˜ by t˜[i] = t[i b i/ncn] for i 0. We define the
sux t˜i of t˜ as t˜i = t˜[i]t˜[i + 1] . . . and t˜i &lt; t˜j for i, j 2 N, i 6= j i↵ either t˜i = t˜j and
i &lt; j or for the smallest ` 0 such that t˜[i + `] 6= t˜[j + `] we have t˜[i + `] &lt; t˜[j + `].
The sux array A of t is defined as the permutation of the numbers 0, 1, . . . , n 1
such that t˜A[i] &lt; t˜A[i+1] for i = 0, 1, . . . , n 2 and the Burrows-Wheeler transform
(BWT) B = b0b1 . . . bn 1 of t is given by bi = t˜[A[i] + n 1] for i = 0, 1, . . . , n 1.
3</p>
    </sec>
    <sec id="sec-2">
      <title>BWT construction by block-wise merging</title>
      <p>
        We give a short high level description of the algorithm by Ferragina et al. in [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ]
as we will be modifying it. Unlike our algorithm it assumes the input string to
have a unique minimal terminator symbol. Given a block size b the input string
t is partitioned into c = dn/be blocks T0, T1, . . . , Tc 1 of roughly equal size. The
algorithm starts by sux sorting the last block, computing its BWT Bc 1 and
the bit array gtc 1 which denotes for each sux in Tc 1 but the first whether it is
smaller or larger than the first. The BWT of Ti . . . Tc 1 for i &lt; c 1 is computed by
first computing the sux array for the suxes starting in Ti by using the text of Ti
and Ti+1 in memory and handling the comparison of suxes starting in Ti but equal
until both have entered Ti+1 by using the bit vector gti+1 which explicitly stores
the result of this comparison. The BWTs of Ti and Ti+1Ti+2 . . . Tc 1 are merged by
computing the ranks of the suxes starting in Ti+1Ti+2 . . . Tc 1 in the sorted set of
suxes of Ti and computing a gap array Gi which denotes how many suxes from
Ti+1Ti+2 . . . Tc 1 are to be placed before the suxes in Ti, between two adjacent
suxes in Ti and after all suxes in Ti. This process follows a backward search
of Ti+1Ti+2 . . . Tc 1 in Ti. Using the array Gi it is simple to merge the two BWTs
together. For computing the rank of a sux from Ti+1 . . . Tc 1 it is necessary to
know whether it is smaller or larger than the one at the start of Ti+1Ti+2 . . . Tc 1 as
Bi is not a conventional BWT. For further details about the algorithm the reader
is referred to [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ].
4
      </p>
    </sec>
    <sec id="sec-3">
      <title>Sorting single blocks</title>
      <p>The algorithm by Ferragina et al processes each single block relying on knowledge
about the priorly fully processed following block, in case of the last block the
terminator. For our algorithm we need to be able to sort a single block without
knowing the complete sorted order of the next block. For this purpose we need to be
able to handle repetitions, one of the major challenges along the way, eciently. For
our block sorting only repetitions with a period not exceeding the maximum block
size are relevant. Consider a block of b suxes t˜i+j for some i 2 N+, 0  j &lt; b. We
say it generates a repetition with period p, 1  p  b i↵ t˜[b p, b 1] = t˜[b, b + p 1]
and propagates a repetition with period p, 1  p  b i↵ t˜i[0, b + 2p 1] has period p.
If it propagates repetitions of any periods, then there is a unique minimal period
dividing all other propagated periods. This unique minimal period can then be
computed in time O(b) and space O(b log ) bits using minor modifications of
standard string algorithms. As there is a unique minimal period propagated by a
block if any and we are only interested in generated periods which are propagated
by the next block we can compute the relevant generation properties of a block
in the same time and space bounds. Given a target block size b0 we partition the
given text into a set of blocks of size either b = d d(n/nb0)e e  b0 or b 1 where the
first n mod b blocks have length b and the rest length b 1. For the propagation of
repetitions we extend the blocks of length b 1 to size b by adding the (circularly)
next character to the right. Using this information about short period repetitions
in the input string, we are able to handle the sorting of a single block of suxes
extending beyond the end of the block eciently by reducing long repetitions.
Lemma 4.1 A block of b circular suxes of t˜ can be sorted in lexicographical order
using time O(b) and space O(b log b) bits using precomputed repetition propagation
data.</p>
      <p>For forward searching using the sux array it is useful to in addition have
the longest common prefix (LCP) array. For two strings u, v let LCP(u, v) =
argmaxlm=i0n{|u|,|v|} u[0, ` 1] = v[0, ` 1]. For a block t˜[i, i + b 1] for i, b 2 N, b &gt; 0
let A denote the permutation of i, i + 1, . . . , i + b 1 such that t˜A[j] &lt; t˜A[j+1] for
j = 0, 1, . . . , b 2. Then the LCP array of the block is defined by LCP[0] = 0 and
LCP[i] = LCP(t˜A[i 1], t˜A[i]) for i = 1, 2, . . . , b 1. Using a repetition reduction
method similar to the sux sorting case we obtain the following result.
Lemma 4.2 The LCP array for a block of b circular suxes on t˜ can be computed
in time O(b) and space O(b log b) bits using precomputed repetition propagation
data.
5</p>
      <p>
        Merging Pairs of Adjacent Blocks
In our modified algorithm we replace the completely skewed binary merge tree used
in [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ] by a balanced binary merge tree. Consequently we will need to be able to
merge blocks with a block size in ⌦( n). For merging two adjacent blocks we need
the following components:
1. The BWT of the left and right block. These can be compressed and in external
memory as they will be scanned sequentially.
2. An internal memory index of the left block suitable for backward search in
O(1) time per step. An FM type index using space blHk + o(n log ) bits can
be used where bl is the length of the left block and Hk denotes the k’th order
entropy of the left block (see [
        <xref ref-type="bibr" rid="ref12">12</xref>
        ]).
3. The gt bit vectors for the left and right block. Scanned sequentially and thus
can be read streaming from external memory.
4. The number of circular suxes in the left block smaller than the rightmost
sux of the right block. Used as the start point for the backward search.
      </p>
      <p>5. The gap array G.</p>
      <p>
        The first three are equivalent to those used in [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ]. The rank of the rightmost
sux in the right block relative to the suxes of the left block can be obtained by
employing forward search on one or more text blocks. If the left block is a single
block which was produced by explicit sux sorting using the method of Section
4, then the rank can be obtained using classical forward search in the sux array
while using the adjoined LCP array. This takes time O(n + log b) in the worst
case (on average this can be expected to be O(log n + log b), see [
        <xref ref-type="bibr" rid="ref15">15</xref>
        ]). If the left
block was already obtained by merging c blocks together, then the desired rank
can be obtained as the sum of the ranks of the sux relative to all single blocks
composing the left block in time O(c(n + log b)). Assuming the blocks are merged
together in a balanced binary merge tree the total time used for forward searches
is O( nb log nb n) in the worst case and O( nb log nb log n) on average. If we choose
b 2 O( long n ) then this becomes O(n log n log log n). The memory required for the
index of the left block in internal memory will be bl log + o(bl log ) for a left
block size of bl assuming that the entropy compression is ine↵ective. This leaves
us with the space required for the gap array. In the original algorithm this is a
conventional array in internal memory taking space O(b log n) bits for a left block
size of b. As we want to be able to merge blocks with size in ⌦( n) this space
requirement is too high. Using Elias code (cf. [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ]) we can store the gap array for
merging a left and right block of length bl and br respectively in O(bl + br) bits
of space. code however is not suitable for ecient updating as we would need it
for computing the gap array. We solve this by producing partial sparse gap arrays
and merging these together as needed. These sparse gap arrays are encoded using
two coded number sequences where one encodes the indices of non-zero values
in di↵erential coding and the other encodes the non-zero values. The array G is
produced by backward searching the suxes of the right block in a suitable index
of the left block. After each step exactly one element of G is incremented. The
sum over the elements of G increases by exactly one for each step. For computing
a complete gap array one option is to start by producing sparse arrays consisting
of a single element of value 1. Whenever we have produced two partial arrays of
sum s we immediately merge them together to a partial array of sum 2s in time
O(s). This method guarantees that the set of sparse gap arrays present at any one
time is bounded in space by O(bl + br) bits. The total merging of partial gap arrays
br
to obtain the final gap array then takes time O(br log br). If we accumulate log2 br
indices for incrementing before writing a partial gap array then we can reduce the
merging time to O(br log log br) without increasing the space used by the algorithm.
      </p>
      <p>The gt array for the merged block can be composed by concatenating the gt
array for the left block and an array storing the respective information for the
right block computed while performing the backward search for filling the gap
array. For this purpose we need to know the rank of the leftmost sux in the
left block. This can either be computed using forward search on the sux arrays
of the basic blocks or extracted from a sampled inverse sux array which can be
computed along the way. The sampled inverse sux arrays of two blocks can just
like the BWTs of the two blocks be merged using the gap array. This is also an
operation based on stream accesses, so it can be done in external memory in time
O(b).
6</p>
      <p>BWT Computation by Balanced Tree Block Merging
Using the building blocks described above we can now describe the complete
algorithm for computing the BWT of t by merging basic blocks according to a balanced
binary tree.</p>
      <p>1. Choose a target block size b0 2 O( long n ) and deduce a block size b = d d bn0 e e
n
n n
such that the number of blocks c satisfies c = d b e = d b0 e and n can be split
into blocks of size b and b 1 only. Split t such that the blocks of size b appear
before those of size b0. This step takes constant space and time.
2. Compute which blocks in t propagate repetitions of period at most b and for
each block which is followed by a block propagating a repetition whether it is
generating this repetition. This takes time O(n) in total and space O(b log ) =
O( nlologgn ) ✓ O(n) bits. The result data can be stored in external memory.
3. Compute a balanced merge tree for the blocks. Start with a root representing
all blocks. If a node containing a single block is considered produce a leaf and
stop. Otherwise for an inner node representing k &gt; 1 blocks produce a left
k k
subtree from the d 2 e leftmost blocks and a right subtree from b 2 c rightmost
blocks in t. The tree has O(log n) nodes. Each node stores at most two (start
and end) block indices taking O(log log n) bits and two node pointers also
taking space O(log log n) bits. So the total tree takes space O(log n log log n)
bits. It can be computed in time O(log n).
4. Sort the blocks and store the resulting BWT, gt and sampled inverse sux
arrays in external memory. Using the sux and LCP arrays of the basic
blocks also compute the start ranks necessary for the backward searches when
merging the blocks together. This takes time O(n log n log log n) in the worst
case and O(n) on average and space O(b log b) = O( long n log long n ) = O(n) bits
of internal memory.
5. Process the merge tree. Mark all leafs as finished and all inner nodes as
unfinished. While there are unfinished nodes choose any unfinished node with only
finished children, merge the respective blocks and mark the node as finished.
There are O(log n) leafs and the tree is balanced, so it has O(log log n) levels.
Each single level can be processed in time O(n log log n). So the total run time
for the tree merging phase is O(n log2 log n). The maximum internal memory
space usage appears when performing the merge operation at the root of the
tree. Here we need space blHk + o(bl log ) bits where bl denotes the sum of
the length of the blocks in the left subtree which is O(n) and Hk denotes the
k’th order entropy of the text comprising those text blocks.</p>
      <p>
        Summing over all steps the run-time of the algorithm is O(n log n log log n) in the
worst case and O(n log2 log n) on average. In practice this means we can compute
the BWT of a text as long as we are able to hold the text (more precisely the text
for the left subtree of the merge tree) in internal memory. If we can hold a fixed
fraction of the text in main memory, then we can still compute the BWT of the
text in the same run-time by resorting to the original iterative merging scheme
from [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ]. We decompose the text into blocks of size b0 such that b0  ncllooggn where
1c is the fixed fraction of the text we can hold in internal memory and compute a
partial BWT for each of these blocks where the suxes sorted are considered as
coming from the whole text, i.e. sux comparisons are still over t˜ and not limited
to a single of the blocks. Then we merge these blocks along a totally skewed
merge tree such that the left block always has size about b0. The size of the set
of partial sparse gap arrays required at any time remains bounded by O(n) bits.
As the number of blocks is fixed, the total asymptotical run-time of the algorithm
remains O(n log n log log n) in the worst case and O(n log2 log n) on average.
7
      </p>
      <p>
        Conclusion
We have presented a new semi external algorithm for computing the
BurrowsWheeler transform. On average our new algorithm is faster then the algorithm of
Ferragina et al published in [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ]. In comparison with the algorithm by Beller et
in [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] our algorithm can be applied for the case when less than 8 bits per symbol
of internal memory are available. Due to space constraints proofs, parallelisation
of our algorithm and the discussion of an implementation study are postponed
to another paper. Sample code implementing parts of the ideas in this paper is
available from the author on request.
      </p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>T.</given-names>
            <surname>Beller</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Zwerger</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Gog</surname>
          </string-name>
          , and
          <string-name>
            <given-names>E.</given-names>
            <surname>Ohlebusch</surname>
          </string-name>
          .
          <article-title>Space-Ecient Construction of the Burrows-Wheeler Transform</article-title>
          . In O. Kurland,
          <string-name>
            <given-names>M.</given-names>
            <surname>Lewenstein</surname>
          </string-name>
          , and E. Porat, editors,
          <source>SPIRE</source>
          , volume
          <volume>8214</volume>
          of Lecture Notes in Computer Science, pages
          <fpage>5</fpage>
          -
          <lpage>16</lpage>
          . Springer,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>T.</given-names>
            <surname>Bingmann</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Fischer</surname>
          </string-name>
          , and
          <string-name>
            <given-names>V.</given-names>
            <surname>Osipov</surname>
          </string-name>
          .
          <article-title>Inducing Sux and LCP Arrays in External Memory</article-title>
          . In P. Sanders and N. Zeh, editors,
          <source>ALENEX</source>
          , pages
          <fpage>88</fpage>
          -
          <lpage>102</lpage>
          . SIAM,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>M.</given-names>
            <surname>Burrows</surname>
          </string-name>
          and
          <string-name>
            <given-names>D.</given-names>
            <surname>Wheeler</surname>
          </string-name>
          . A
          <string-name>
            <surname>Block-Sorting Lossless Data Compression Algorithm</surname>
          </string-name>
          .
          <source>Digital Systems Research Center. RR-124</source>
          ,
          <year>1994</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>M.</given-names>
            <surname>Crochemore</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Grossi</surname>
          </string-name>
          ,
          <string-name>
            <surname>J.</surname>
          </string-name>
          <article-title>K¨arkk¨ainen, and</article-title>
          <string-name>
            <given-names>G. M.</given-names>
            <surname>Landau</surname>
          </string-name>
          .
          <article-title>A ConstantSpace Comparison-Based Algorithm for Computing the Burrows-Wheeler Transform</article-title>
          .
          <source>In J. Fischer and P</source>
          . Sanders, editors,
          <source>CPM</source>
          , volume
          <volume>7922</volume>
          of Lecture Notes in Computer Science, pages
          <fpage>74</fpage>
          -
          <lpage>82</lpage>
          . Springer,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>R.</given-names>
            <surname>Dementiev</surname>
          </string-name>
          , J. K¨arkk¨ainen, J. Mehnert, and
          <string-name>
            <given-names>P.</given-names>
            <surname>Sanders</surname>
          </string-name>
          .
          <article-title>Better external memory sux array construction</article-title>
          .
          <source>ACM Journal of Experimental Algorithmics</source>
          ,
          <volume>12</volume>
          ,
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>P.</given-names>
            <surname>Elias</surname>
          </string-name>
          .
          <article-title>Universal codeword sets and representations of the integers</article-title>
          .
          <source>Information Theory</source>
          , IEEE Transactions on,
          <volume>21</volume>
          (
          <issue>2</issue>
          ):
          <fpage>194</fpage>
          -
          <lpage>203</lpage>
          ,
          <year>1975</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>P.</given-names>
            <surname>Ferragina</surname>
          </string-name>
          ,
          <string-name>
            <given-names>T.</given-names>
            <surname>Gagie</surname>
          </string-name>
          , and
          <string-name>
            <given-names>G.</given-names>
            <surname>Manzini</surname>
          </string-name>
          .
          <article-title>Lightweight Data Indexing and Compression in External Memory</article-title>
          . Algorithmica,
          <volume>63</volume>
          (
          <issue>3</issue>
          ):
          <fpage>707</fpage>
          -
          <lpage>730</lpage>
          ,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>P.</given-names>
            <surname>Ferragina</surname>
          </string-name>
          and
          <string-name>
            <given-names>G.</given-names>
            <surname>Manzini</surname>
          </string-name>
          .
          <article-title>Opportunistic Data Structures with Applications</article-title>
          .
          <source>In Foundations of Computer Science</source>
          ,
          <year>2000</year>
          .
          <source>Proceedings. 41st Annual Symposium on</source>
          , pages
          <fpage>390</fpage>
          -
          <lpage>398</lpage>
          . IEEE,
          <year>2000</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>W.-K.</given-names>
            <surname>Hon</surname>
          </string-name>
          ,
          <string-name>
            <given-names>K.</given-names>
            <surname>Sadakane</surname>
          </string-name>
          , and
          <string-name>
            <given-names>W.-K.</given-names>
            <surname>Sung</surname>
          </string-name>
          .
          <article-title>Breaking a Time-and-Space Barrier in Constructing Full-Text Indices</article-title>
          .
          <source>In FOCS</source>
          , pages
          <fpage>251</fpage>
          -
          <lpage>260</lpage>
          . IEEE Computer Society,
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <surname>J. K</surname>
          </string-name>
          <article-title>¨arkk¨ainen and</article-title>
          <string-name>
            <given-names>P.</given-names>
            <surname>Sanders</surname>
          </string-name>
          .
          <article-title>Simple Linear Work Sux Array Construction</article-title>
          .
          <source>In Automata, Languages and Programming</source>
          , pages
          <fpage>943</fpage>
          -
          <lpage>955</lpage>
          . Springer,
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <given-names>U.</given-names>
            <surname>Manber</surname>
          </string-name>
          and
          <string-name>
            <given-names>G.</given-names>
            <surname>Myers. Sux</surname>
          </string-name>
          <article-title>Arrays: a New Method for On-line String Searches</article-title>
          .
          <source>SIAM Journal on Computing</source>
          ,
          <volume>22</volume>
          (
          <issue>5</issue>
          ):
          <fpage>935</fpage>
          -
          <lpage>948</lpage>
          ,
          <year>1993</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <string-name>
            <given-names>G.</given-names>
            <surname>Navarro</surname>
          </string-name>
          and
          <string-name>
            <surname>V.</surname>
          </string-name>
          <article-title>M¨akinen</article-title>
          .
          <source>Compressed Full-Text Indexes. ACM Computing Surveys (CSUR)</source>
          ,
          <volume>39</volume>
          (
          <issue>1</issue>
          ):
          <fpage>2</fpage>
          ,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [13]
          <string-name>
            <given-names>G.</given-names>
            <surname>Nong</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Zhang</surname>
          </string-name>
          , and
          <string-name>
            <given-names>W. H.</given-names>
            <surname>Chan</surname>
          </string-name>
          .
          <article-title>Two Ecient Algorithms for Linear Time Sux Array Construction</article-title>
          . Computers, IEEE Transactions on,
          <volume>60</volume>
          (
          <issue>10</issue>
          ):
          <fpage>1471</fpage>
          -
          <lpage>1484</lpage>
          ,
          <year>2011</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          [14]
          <string-name>
            <given-names>D.</given-names>
            <surname>Okanohara</surname>
          </string-name>
          and
          <string-name>
            <given-names>K.</given-names>
            <surname>Sadakane</surname>
          </string-name>
          .
          <article-title>A Linear-Time Burrows-Wheeler Transform Using Induced Sorting</article-title>
          . In J. Karlgren,
          <string-name>
            <given-names>J.</given-names>
            <surname>Tarhio</surname>
          </string-name>
          , and H. Hyyr¨o, editors,
          <source>SPIRE</source>
          , volume
          <volume>5721</volume>
          of Lecture Notes in Computer Science, pages
          <fpage>90</fpage>
          -
          <lpage>101</lpage>
          . Springer,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          [15]
          <string-name>
            <given-names>W.</given-names>
            <surname>Szpankowski</surname>
          </string-name>
          .
          <article-title>On the Height of Digital Trees</article-title>
          and
          <string-name>
            <given-names>Related</given-names>
            <surname>Problems</surname>
          </string-name>
          . Algorithmica,
          <volume>6</volume>
          (
          <issue>1</issue>
          -6):
          <fpage>256</fpage>
          -
          <lpage>277</lpage>
          ,
          <year>1991</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>