Abstract 1 Introduction 2 Order-preserving Suffix Tree Path Decompositions 3 Preliminary experimental results References

Compressing Suffix Trees by Path Decompositions

Ruben Becker ORCID Ca’ Foscari University of Venice, Italy    Davide Cenzato ORCID Ca’ Foscari University of Venice, Italy    Travis Gagie ORCID Dalhousie University, Halifax, Canada    Ragnar Groot Koerkamp ORCID ETH Zurich, Switzerland
Karlsruhe Institute of Technology, Germany
   Sung-Hwan Kim ORCID Ca’ Foscari University of Venice, Italy
Sant’Anna School of Advanced Studies, Pisa, Italy
   Giovanni Manzini ORCID University of Pisa, Italy    Nicola Prezza ORCID Ca’ Foscari University of Venice, Italy
Abstract

The suffix tree is arguably the most fundamental data structure on strings: introduced by Weiner (SWAT 1973) and McCreight (JACM 1976), it allows solving a myriad of computational problems on strings in linear time. Motivated by its large space usage, subsequent research focused first on reducing its size by a constant factor via Suffix Arrays, and later on reaching space proportional to the size of the compressed string. Modern compressed indexes, such as the r-index (Gagie et al., JACM 2020), fit in space proportional to r, the number of runs in the Burrows-Wheeler transform (a strong and universal repetitiveness measure). These advances, however, came with a price: while modern compressed indexes boast optimal bounds in the RAM model, they are often orders of magnitude slower than uncompressed counterparts in practice due to catastrophic cache locality. This reality gap highlights that Big-O complexity in the RAM model has become a misleading predictor of real-world performance, leaving a critical question unanswered: can we design compressed indexes that are efficient in the I/O model of computation?

We answer this in the affirmative by introducing a new Suffix Array sampling technique based on particular path decompositions of the suffix tree. We prove that sorting the suffix tree leaves by specific priority functions induces a decomposition where the number of distinct paths (each corresponding to a string suffix) is bounded by r. This allows us to solve indexed pattern matching efficiently in the I/O model using a Suffix Array sample of size at most r, strictly improving upon the (tight) 2r bound of Suffixient Arrays, another recent compressed Suffix Array sampling technique.

Experiments confirm that this theoretical I/O efficiency translates to practice in pangenomic applications: our index locates pattern occurrences using less space and orders of magnitude less time than the r-index when performing pattern matching on repetitive DNA collections. Beyond this, our contributions are twofold: (i) unlike Suffixient Arrays, our technique supports most standard suffix tree operations in O(r) space on top of the text while matching the I/O complexity of uncompressed suffix trees; and (ii) we establish a general framework where any valid path decomposition induces a Suffix Array sampling whose size is a new strong repetitiveness measure; we provide a universal mechanism for locating all pattern occurrences for each such path decomposition.

Keywords and phrases:
Text indexing, suffix tree, I/O-efficient, Compressed Data Structures
Category:
Track A: Algorithms, Complexity and Games
Funding:
Travis Gagie: Funded by NSERC (Discovery Grant RGPIN-07185-2020).
Copyright and License:
[Uncaptioned image] © Ruben Becker, Davide Cenzato, Travis Gagie, Ragnar Groot Koerkamp,
Sung-Hwan Kim, Giovanni Manzini, and Nicola Prezza; licensed under Creative Commons License CC-BY 4.0
2012 ACM Subject Classification:
Theory of computation Pattern matching
; Theory of computation Data structures design and analysis ; Theory of computation Data compression
Related Version:
Full Version: https://arxiv.org/abs/2506.14734 [4]
Supplementary Material:
Software  (Source Code): https://github.com/regindex/STPD-index [3]
  archived at Software Heritage Logo swh:1:dir:d4f76a2be744c622f98d403443e3f4507ae9b536
Funding:
Ruben Becker, Davide Cenzato, Sung-Hwan Kim, and Nicola Prezza: Funded by the European Union (ERC, REGINDEX, 101039208). Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union or the European Research Council Executive Agency. Neither the European Union nor the granting authority can be held responsible for them.
Ruben Becker and Giovanni Manzini: Funded by INdAM-GNCS (INdAM-GNCS Project CUP E53C25002010001).
Editors:
Sayan Bhattacharya, Danupon Nanongkai, Michael Benedikt, and Gabriele Puppis

1 Introduction

In this paper, we describe a new elegant and very efficient paradigm to solve the well-studied problem of compressing suffix trees. Suffix trees were introduced in 1973 by Weiner [48] and revisited (in their modern form) in 1976 by McCreight [36] to solve string processing problems such as finding longest common substrings and matching patterns on indexed text in linear time. The latter problem (indexed string matching) asks to build a data structure on a text 𝒯 of length n over alphabet of size σ so that later (at query time), given a string P (the pattern) of length mn, the following can be returned: (1) one exact occurrence 𝒯[i,j]=P of P in 𝒯 if any exists (find queries), (2) all exact occurrences of P in 𝒯 (locate queries), or (3) the number of exact occurrences of P in 𝒯 (count queries). While being extremely fast due to excellent query-time cache locality, suffix trees require a linear number of words to be stored in memory regardless of the input compressibility and are therefore not suitable to nowadays massive-data scenarios such as pan-genome indexing (where one aims at indexing terabytes of data in the form of repetitive collections of thousands of genomes). This problem was later mitigated by Suffix Arrays [35, 34, 22], which use only a constant fraction of the space of suffix trees while supporting (cache-efficiently) a subset of their functionality, still sufficient to support pattern matching queries.

Subsequent research succeeded (spectacularly) in reducing the space usage of suffix trees and Suffix Arrays to the bare minimum needed to store the compressed text. Notable contributions in this direction include the compressed Suffix Array (CSA) [23], FM-index [18], run-length compressed Suffix Array [33], run-length FM-index [32], r-index [21], Lempel-Ziv-based [29] and indexes based on straight-line programs (SLPs) [14] (and their variants), and the more recent δ-SA [26]. See the survey of Navarro [39] for an extensive treatment of the subject. While the first line of work (CSA and FM-index) focused on entropy compression, the subsequent works mentioned above switched to text compressors capable of exploiting the repetitiveness of the underlying text sequence (a source of redundancy that entropy compression is not able to exploit). Among those, the r-index [20, 21] and its improvements [41, 7, 51] stood out for its optimal linear-time pattern matching query time and its size – linear in the number r of equal-letter runs in the Burrows-Wheeler transform (BWT) of the text. These works on repetition-aware compressed text indexes spurred a very fruitful line of research on compressibility measures (the survey of Navarro [38] covers the subject in detail), culminating in recent breakthroughs [27, 25] which showed that r is a strong and universal repetitiveness measure, being equivalent to all other known compressibility measures (such as the size of the Lempel-Ziv factorization [31], normalized substring complexity [28], and straight-line programs) up to a multiplicative polylogarithmic factor. Altogether, these results laid the theoretical foundations for subsequent works in computational pan-genomics that showed how the run-length encoded BWT can successfully be used to index very large collections of related genomes in compressed space [45, 16, 44, 2, 46, 1].

1.1 Are repetition-aware data structures just a theoretical tool?

Modern compressed indexes such as the δ-SA of Kempa and Kociumaka [26] support random access and pattern matching queries, but their time complexities depend on a high polynomial of the logarithm of the text’s length, which makes them hardly practical. Indexes based on the Lempel-Ziv factorization or on grammar compression mitigate this problem (even reaching optimal search time [13]), but rely on complex and cache-inefficient data structures that, again, make them orders of magnitude slower than simple suffix trees in practice. The r-index (in its modern version [41]) uses O(r) words of space and solves find, locate, and count queries in O(m) time (assuming constant alphabet for simplicity), plus the number of occurrences to be reported (if any). While this is essentially the end of the story in the word RAM model, it does not take into account caching effects. As a matter of fact, each of the O(m) steps of the backward search algorithm of the r-index and of its predecessor (the FM-index [18]) triggers I/O operations (that is, likely cache misses). While this issue was later partially addressed by the move structure of Nishimoto and Tabei [41], that solution still triggers O(m) cache misses. This does not happen with the suffix tree:

 Remark 1.

The suffix tree of Weiner [48] and McCreight [36] uses O(n) words on top of the plain text (nlogσ bits) and allows locating all the occ occurrences of any pattern P of length m with O(d+m/B+occ) I/O complexity, where d is the node depth of P in the suffix tree and B is the number of integers fitting in an I/O block.

To see this, observe that path compression makes it possible to compare (a substring of) the pattern with the label of an edge of length with O(/B+1) I/O complexity. In particular, each of the d edge traversals triggers at least one I/O operation in the worst case. The additive term d is negligible in practice as in most interesting scenarios the suffix tree tends to branch mostly in the highest levels (we investigate this effect in the full version of this paper [4]). For instance, if the text is uniform then dΘ(logn) with high probability since the longest repeated substring’s length is Θ(logn) w.h.p.

The performance gap in the I/O model between compressed indexes and the suffix tree shows up dramatically in practice: a simple experiment (see [4]) shows that, while the r-index is orders of magnitude smaller than the suffix tree on very repetitive inputs, it also solves queries orders of magnitude slower. The same holds true for all the existing compressed indexes using a space close to that of the r-index. This reality gap highlights that Big-O complexity in the RAM model has become a misleading predictor of real-world performance in the context of compressed data structures, leaving a critical question unanswered:

Can compressed indexes be efficient in the I/O model of computation?

1.2 Our contributions

We answer this question in the affirmative by introducing a novel compressed sampling of the Prefix Array. In one configuration, our sampling requires at most r samples to resolve pattern matching queries via a simple binary search strategy, assuming random access to the text is available. Since random access in compressed space is a well-studied problem [8, 29, 6, 30] (see also [38] for a survey on the topic), this requirement does not limit our strategy. On the contrary, unlike existing compressed indexes, our approach is flexible enough to utilize any random access compressed data structure.

By incorporating additional data structures, we achieve our main result: a compressed suffix tree topology occupying only O(r) words of space on top of a (potentially compressed) text oracle that still efficiently supports most standard navigation queries:

Theorem 2.

Let 𝒯 be a text of length n over an integer alphabet of size σ. Assume we have access to an oracle supporting longest common extension (lce) and random access queries (extraction of one character) on 𝒯 in O(t) time. Then, there is a representation of 𝒯’s suffix tree using O(r) words on top of the text oracle and supporting these queries:

  • 𝑟𝑜𝑜𝑡() in O(1) time: the suffix tree root.

  • 𝑐ℎ𝑖𝑙𝑑(u,a) in O(tlogr+logσ) time: the child of node u by letter a.

  • 𝑓𝑖𝑟𝑠𝑡(u) in O(logσ) time: the alphabetically-smallest label among the outgoing edges of u.

  • 𝑠𝑢𝑐𝑐(u,a) in O(logσ) time: given node u and a character a labeling one of the outgoing edges of u, return the successor of a (in alphabetic order) among the characters labeling outgoing edges of u (return if no such label exists).

  • 𝑙𝑎𝑏𝑒𝑙(u,v) in O(1) time: given an edge (u,v), return (i,j)[n]2 such that the edge’s label is 𝒯[i,j].

  • 𝑙𝑙𝑒𝑎𝑓(u), 𝑟𝑙𝑒𝑎𝑓(u) in O(1) time: the leftmost/rightmost leaves of the subtree rooted in a given node u.

  • 𝑛𝑒𝑥𝑡(u): if u is a leaf, return the next leaf in lexicographic order; we support following a sequence of k leaf pointers in O(loglog(n/r)+k) time.

  • 𝑙𝑜𝑐𝑎𝑡𝑒(u) in O(1) time: the text position i of a given leaf (representing suffix 𝒯[i,n]).

  • 𝑠𝑑𝑒𝑝𝑡ℎ(u) in O(1) time: the string depth of node u.

  • 𝑎𝑛𝑐𝑒𝑠𝑡𝑜𝑟(u,v) in O(t) time: whether u is an ancestor of v.

If the text oracle also supports computing a collision-free (on text substrings) hash κ(𝒯[i,j]) of any text substring in O(h) time (an operation we call fingerprinting), then 𝑐ℎ𝑖𝑙𝑑(u,a) can be supported in O(t+hlogn+logσ) time within the same asymptotic space.

The same asymptotic bounds apply to I/O complexity if t and h represent I/O costs rather than time.

A subset of the above queries suffices to navigate the suffix tree (a task at the core of several string-processing algorithms) and to solve pattern matching queries. For example, using the cache-efficient text representation of Prezza [42], supporting lce with O(t)=O(logn) I/O complexity, fingerprinting with O(h)=O(1) I/O complexity, and extraction of contiguous characters with O(1+/B) I/O complexity on polynomial alphabets, we obtain the following:

Corollary 3.

Let 𝒯 be a text of length n over an integer alphabet of size σ. The topology of 𝒯’s suffix tree can be compressed in O(r) words on top of a text representation [42] of nlogσ+O(logn) bits so that all the occ occurrences of any pattern P of length m can be located with O(dlogn+m/B+occ) I/O complexity, where d is the node depth of P in the suffix tree and B is the number of integers fitting in an I/O block.

That is, the same I/O complexity of Weiner and McCreight’s suffix tree up to a logarithmic factor multiplying d (see Remark 1). At the same time, the space usage on top of the text is reduced from O(n) to O(r) words (r is orders of magnitude smaller than n on very repetitive inputs [21]). Furthermore, the term dlogn can be replaced by dlogm with a different technique (Theorem 40; this is important since in typical applications, mn holds).

Using up-to-date cache-efficient compressed data structures, we show experimentally that an optimized implementation of our fully-compressed index is simultaneously smaller and orders of magnitude faster than the r-index on the task of locating all pattern occurrences on a highly repetitive collection of genomes.

1.3 Improvements over related techniques

Suffixient Array.

Our approach is most closely related to the Suffixient Array [10], another recent compressed sampling of the Prefix Array. We strictly improve upon the Suffixient Array in three dimensions:

  • Space Bounds. The Suffixient Array requires up to 2r samples [40], a bound recently proven to be worst-case tight up to a small additive constant [17]. Our technique demonstrates that r samples are sufficient for pattern matching.

  • Functionality. Unlike Suffixient Arrays, which are limited to pattern matching, our sampling retains the topological structure of the suffix tree. Consequently, we support a much broader range of suffix tree operations efficiently.

  • Locating Efficiency. Suffixient Arrays return an arbitrary pattern occurrence, offering no control over which one is found. To locate all occurrences starting from an arbitrary position SA[i], one requires bidirectional navigation (both SA[i1] and SA[i+1]), costing about 4r words of auxiliary space [21]. In contrast, one of the configurations of our index guarantees returning the first pattern occurrence in Suffix Array order. This allows us to locate all remaining occurrences using only unidirectional successor Suffix Array queries (i.e., retrieving SA[i+1] given SA[i]) with 2r words of auxiliary space [21].

Compressed Suffix Trees.

Gagie et al. [21] previously addressed compressed suffix trees in space bounded by a function of r, showing that full functionality is possible in O(rlog(n/r)) space with logarithmic operation time. When augmented with a I/O efficient text oracle, their theoretical I/O complexity for pattern matching matches our Corollary 3; however, their approach consumes significantly more space on top of the oracle (O(rlog(n/r)) vs O(r)). Furthermore, their structure relies on complex machinery atop a grammar-compressed Suffix Array; to our knowledge, it has never been implemented, likely due to the practical reality that Suffix Arrays do not compress as effectively as the text itself via grammar compression.

Other I/O Efficient Solutions.

Other works in the literature addressed the I/O-efficiency of full-text indexes. Chien et al. [12] introduced the Geometric Burrows-Wheeler Transform, which connects range searching with text indexing to provide compressed indexing techniques and theoretical lower bounds within the I/O model. Their solution, however, achieves I/O-efficient performance only in the uncompressed setting. Similarly, Ferragina and Venturini [19] proposed a compressed version of the string B-tree, adapting classical external-memory string structures to use compressed space while remaining efficient across memory hierarchies. While their compressed cache-oblivious string B-Tree supports I/O-efficient prefix search and enumeration, its space for locate queries remains proportional to the number of suffixes.

As far as fully-compressed space is concerned, several recent works have targeted the I/O bottleneck of the r-index. The Move structure of Nishimoto and Tabei [41] reduces the I/O operations of the r-index by a loglogn factor by replacing predecessor queries with pointers. However, it retains a worst-case complexity of O(m+occ) I/O operations. While practical implementations [51, 7] are roughly an order of magnitude faster than the standard r-index, they require significantly more space. Similarly, Puglisi and Zhukova [43] applied relative Lempel-Ziv compression to a transformed Suffix Array. While this yields good memory locality and query speeds in practice, it lacks formal guarantees and increases the space usage of the r-index by an order of magnitude, again suffering from the poor compressibility of the Suffix Array relative to the text.

2 Order-preserving Suffix Tree Path Decompositions

Due to space limitations, we assume the reader to be already familiar with the following standard concepts: right-maximal strings, lexicographic and colexicographic order, longest common suffix/prefix function lcp(α,β) / lcs(α,β) between strings, Suffix Array, suffix tree, and Burrows-Wheeler transform. See the full version [4] for the formal definitions.

Definition 4 (rlce, llce, and lce).

Let 𝒮 be a string of length n. The right (left) longest common extension function 𝒮.rlce (𝒮.llce) is the function that, for two distinct integers i,j[n], returns 𝒮.rlce(i,j)=lcp(𝒮[i,n],𝒮[j,n]) (𝒮.llce(i,j)=lcs(𝒮[1,i],𝒮[1,j])). A longest common extension (lce) oracle is an oracle that supports both 𝒮.rlce and 𝒮.llce queries for the string 𝒮.

When clear from the context, we simply write rlce and llce instead of 𝒮.rlce and 𝒮.llce.

Our work can be interpreted as a generalization of suffix sorting: by sorting the text’s suffixes according to any priority function (permutation) π:[n][n] satisfying a natural and desirable order-preserving property (see Definition 5), we obtain a compressed index that keeps track of the pattern occurrence 𝒯[i,j] minimizing π(i) among all pattern occurrences. Figure 1 broadly introduces our solution. Intuitively, we (i) sort the suffix tree’s leaves according to π, (ii) we build a suffix tree path decomposition (STPD for brevity) prioritizing the paths with smaller π, and (iii) we path-compress the STPD paths by just recording their starting position in the text. At this point, we show that the colexicographically-sorted Path Decomposition Array PDA of those positions (a sample of the Prefix Array) can be used to obtain a new elegant, simple, and remarkably efficient compressed suffix tree.

Figure 1: Overview of our technique. We sort 𝒯’s suffixes 𝒯[i,n] (equivalently, suffix tree leaves) by increasing π(i). In this example, π corresponds to the standard lexicographic order of the text’s suffixes (but π can be more general). This induces a suffix tree path decomposition (an edge-disjoint set of node-to-leaf paths covering all edges) obtained by always following the leftmost path. At this point, we associate each path with the integer i such the path’s label is 𝒯[i,n] (in the figure, we also color each path according to the color of the associated position i). In particular, the label from the root to the first path’s edge is αi,k=𝒯[ik+1,i], where k is the string depth of the first path’s edge. Our indexing strategy essentially consists in implicitly colexicographically-sorting strings αi,k in a subset of the Prefix Array called the Path Decomposition Array PDA: the colexicographically-sorted array containing (without duplicates) the first position of each path (in our example: PDA=[11,10,3,7,8]). Observe that, in this example, there are few (five) distinct path labels: indeed, we show that |PDA| is bounded by universal compressibility measures and that it can be used to support basic suffix tree navigation and pattern matching operations.

As introduced above, the starting point of our technique is the choice of a priority function (permutation) π:[n][n] that we use to generalize suffix sorting. In this paper, we focus on permutations possessing the following natural property.

Definition 5 (Order-preserving permutation).

Let 𝒮Σn be a string and π:[n][n] be a permutation. The permutation π is said to be order-preserving for 𝒮 if and only if π(i)<π(j)𝒮[i,i+1]=𝒮[j,j+1] implies π(i+1)<π(j+1) for all i,j[n1].

The above property is sufficient and necessary to guarantee the following desirable universal minimization property: if 𝒮[i,j]=𝒮[i,j] are two pattern occurrences, then π(i+k)<π(i+k) either holds for all k[0,ji] or for none. In Lemmas 15 and 41 we will show that the lexicographic rank of suffixes, the colexicographic rank of prefixes, and the identity function are order-preserving permutations (but not the only ones).

Suffix tree path decomposition.

A suffix tree path decomposition (STPD) is an edge-disjoint collection of node-to-leaf paths covering all the suffix tree’s edges built as follows. Since we will never start a path on an implicit suffix tree node, we can equivalently reason about path decompositions of the suffix trie. We describe how to obtain the STPD associated with a given order-preserving permutation π, as we believe this will help the reader to better understand our technique. Then, we will make the construction fully formal. Let 𝒯Σn be a text. Imagine the process of inserting 𝒯’s suffixes 𝒯[i,n] (for i[n]) in a trie in order of increasing π(i). The path associated with the first suffix 𝒯[π1(1),n] in this order is the one starting in the root and continuing with characters 𝒯[π1(1),n]. When inserting the j-th (j>1) suffix 𝒯[π1(j),n], let k=maxj<jrlce(π1(j),π1(j)) be the longest common prefix between the j-th suffix and all the previous suffixes in the order induced by π. The corresponding new path in the decomposition is the one starting in the suffix tree locus of string 𝒯[π1(j),π1(j)+k1] and labeled with string 𝒯[π1(j)+k,n]. In other words, the path associated with 𝒯[π1(j),n] is its suffix that “diverges” from the trie containing the previous suffixes in the order induced by π. See Figure 1, where leaves (suffixes) 𝒯[i,n] are sorted left-to-right in order of increasing π(i) where π=ISA.

The core of our indexing strategy is to store in a colexicographically-sorted array PDA all the distinct integers π1(j)+k obtained in this process (that is, the starting positions of paths in 𝒯). We now formalize this intuition. Due to space limitations, most proofs are deferred to the full version of this article [4].

𝐋𝐏𝐅 and 𝐏𝐃𝐀 arrays.

We first introduce the concept of the Generalized Longest Previous Factor Array LPFπ. Intuitively, this array stores the lengths of the longest common prefixes of a string’s suffixes in the order induced by π. It generalizes the well-known Permuted Longest Common Prefix (PLCP) array (when taking π=ISA to be the lexicographic rank of the text’s suffixes) and the LPF array (when taking π=id to be the identity function).

Definition 6 (Generalized Longest Previous Factor Array LPF𝒮,π).

Let 𝒮Σn be a string and π:[n][n] be a permutation. The generalized Longest Previous Factor array LPF𝒮,π[1,n] associated with 𝒮 and π is the integer array that, for i[n], is defined as:

LPF𝒮,π[i]={0 ifπ(i)=1,maxπ(j)<π(i)rlce(j,i) otherwise.
Definition 7 (Path Decomposition Array PDA𝒮,π).

Let 𝒮Σn be a string and π:[n][n] be an order-preserving permutation. The (suffix tree) Path Decomposition Array PDA𝒮,π associated with 𝒮 and π is the set {j=i+LPF𝒮,π[i]:i[n]} sorted in colexicographic order of the corresponding string’s prefixes 𝒮[1,j].

It will always be the case that the indexed string 𝒮 is fixed in our discussion, so we will simply write LPFπ and PDAπ instead of LPF𝒮,π and PDA𝒮,π, respectively. When also π is clear from the context, we will write LPF and PDA.

Example 8.

Consider the STPD of Figure 1. In this example, π(i) is the rank of leaf i in lexicographic order (in other words, π=ISA): π=(4,5,8,11,7,10,6,9,3,2,1). Then, the LPF array corresponds to the PLCP array: LPF=PLCP=[2,1,4,3,2,1,0,0,1,0,0]. For instance, LPF[1]=2 because π(1)=4 and the suffixes 𝒯[j,n] with π(j)<π(1) are those starting in positions j{11,10,9}. Among those, the one with the longest common prefix with 𝒯[1,n] is 𝒯[9,n], and their longest common prefix is 2=LPF[1].

At this point, the sequence i+LPF[i] for i=1,,n is equal to (3,3,7,7,7,7,7,8,10,10,11). The Path Decomposition Array is the array containing the distinct values in such a sequence, sorted colexicographically: PDA=[11,10,3,7,8] (that is, j precedes j in the order if and only if 𝒯[1,j] is colexicographically smaller than 𝒯[1,j]).

The STPD associated with π and the corresponding array PDAπ are said to be order-preserving if π is order-preserving.

The expert reader might have noticed that, for the permutation π used in Example 8, the values in PDA are in a one-to-one correspondence with the irreducible LCP values. As a matter of fact, our technique generalizes the notion of irreducible values to any array LPFπ such that π is order-preserving. First, note that the array LPFπ is almost nondecreasing:

Lemma 9.

For any string 𝒮Σn, if π is order-preserving then LPFπ[i]LPFπ[i1]1 for every i>1. In particular, the sequence i+LPFπ[i], for i=1,,n, is nondecreasing.

Values where the inequality of Lemma 9 is strict are of particular interest:

Definition 10 (Irreducible LPFπ position).

Let 𝒮Σn be a string and π:[n][n] be an order-preserving permutation. We say that i[n] is an irreducible LPFπ position if and only if either i=1 or LPFπ[i]LPFπ[i1]1.

It is a simple observation that LPFπ[i]=LPFπ[i1]1 is equivalent to (i1)+LPFπ[i1]=i+LPFπ[i], from which we obtain:

 Remark 11.

For any order-preserving permutation π:[n][n], {xPDAπ}={i+LPFπ[i]:iisanirreducibleLPFπposition}, hence |PDAπ| is equal to the number of irreducible LPFπ positions (since PDAπ contains distinct values).

The following lemma generalizes the well-known relation between irreducible PLCP values and the Burrows-Wheeler transform [24, Lemma 4] in more general terms.

Lemma 12.

Let 𝒮Σn be a string and π:[n][n] be an order-preserving permutation. Let moreover i>1 be an irreducible LPFπ position. Then, for every j>1 with π(j1)<π(i1) and rlce(i,j)=LPFπ[i], it holds that 𝒮[i1]𝒮[j1].

We will use Remark 11 and Lemma 12 to bound the size of our compressed suffix tree.

Lemma 13 formalizes the following intuitive fact about order-preserving STPDs. Consider an STPD built on string 𝒮 using order-preserving permutation π. If for a suffix tree node u=locus(α), the three nodes parent(u), u, and 𝑐ℎ𝑖𝑙𝑑(u,a) belong to the same STPD path (for some aΣ), then for any other outgoing label bΣ of node u, string αb suffixes at least one sampled prefix 𝒮[1,t], for some tPDAπ.

Lemma 13.

Let 𝒮Σn be a string and π:[n][n] be an order-preserving permutation.

For αΣ and aΣ such that αa occurs in 𝒮, let π(αa)=min{π(i1):𝒮[1,i]issuffixedbyαa}. Then, for any characters a,bΣ such that both αa and αb occur in 𝒮 and π(αa)<π(αb), there exists tPDAπ such that 𝒮[1,t] is suffixed by αb.

We conclude with the following result, implying that |PDAπ| is a reachable compressibility measure for any order-preserving π.

Theorem 14.

Let 𝒮Σn be a string over integer alphabet Σ and let π:[n][n] be an order-preserving permutation. Then, 𝒮 can be compressed in O(|PDAπ|logn) bits of space.

Proof.

(Sketch) For each irreducible LPFπ position i, we store a quadruple (i,LPFπ[i],si,𝒮[i+LPFπ[i]]), where si[n] is the source of i, that is, any integer with π(si)<π(i) and 𝒮[si,si+LPFπ[i]1]=𝒮[i,i+LPFπ[i]1]. This set of quadruples takes O(|PDAπ|log(nσ))=O(|PDAπ|logn) bits of space by Remark 11, and we can reconstruct any character 𝒮[j] given j[n] by recursively following the source position.

We proceed as follows. First, we discuss the notable order-preserving permutation given by the lexicographic rank of the text’s suffixes (Section 2.1). This permutation will enable us to support most suffix tree operations in O(r) space on top of the text oracle. Then, in Section 2.2 we describe a general locating mechanism working on any order-preserving STPD. After that, we focus on the colexicographic rank of the text’s prefixes (Section 2.3). This case is particularly interesting because it allows us to simplify the locating algorithm of Section 2.2, and will lead to a practical solution. Finally, in Section 2.4 we consider yet another remarkable order-preserving permutation: identity. This permutation will allow us to locate efficiently the leftmost and rightmost pattern occurrences.

2.1 Lexicographic rank (𝚜𝚝-𝚕𝚎𝚡): suffix tree navigation

Figure 1 depicts the STPD obtained by choosing π=ISA=SA1 to be the Inverse Suffix Array (in this subsection, π will always be equal to ISA). We denote with 𝚜𝚝-𝚕𝚎𝚡=PDAπ the path decomposition array associated with this permutation π. Similarly, 𝚜𝚝-𝚕𝚎𝚡+ denotes the path decomposition array associated with the dual permutation π¯(i)=nISA[i]+1. The following properties hold:

Lemma 15.

Let 𝒯Σn be a text. The permutations π,π¯ defined as π(i)=ISA[i] and π¯(i)=nISA[i]+1 for i[n] are order-preserving for 𝒯. Furthermore, it holds that |𝚜𝚝-𝚕𝚎𝚡|r and |𝚜𝚝-𝚕𝚎𝚡+|r.

2.1.1 Data structure

Let 𝒯Σn be a text. We describe a data structure of O(r) space supporting the suffix tree queries of Theorem 2 on top of any text oracle supporting Longest Common Extension (and, optionally, fingerprinting) queries on 𝒯. We store the following components.

  1. (1)

    The array 𝚜𝚝-𝚕𝚎𝚡 containing the integers {j=(i1):i𝚜𝚝-𝚕𝚎𝚡𝚜𝚝-𝚕𝚎𝚡+{n+1}}{0,,n} sorted increasingly according to the colexicographic order of the corresponding text prefixes 𝒯[1,j] (if j=0, then 𝒯[1,j] is the empty string). Note that, by Lemma 15, it holds that |𝚜𝚝-𝚕𝚎𝚡|2r+1.

  2. (2)

    Let #Σ be a new character not appearing in Σ (taken to be larger than all the characters in Σ). We store a string [1,|𝚜𝚝-𝚕𝚎𝚡|](Σ{#})|𝚜𝚝-𝚕𝚎𝚡| defined as:

    [i]={#if 𝚜𝚝-𝚕𝚎𝚡[i]=n,𝒯[𝚜𝚝-𝚕𝚎𝚡[i]+1]otherwise.

    We store with a wavelet tree [37], taking O(|𝚜𝚝-𝚕𝚎𝚡|) space and supporting rank and select operations in O(logσ) time.

  3. (3)

    The string [1,|𝚜𝚝-𝚕𝚎𝚡|](Σ{#})|𝚜𝚝-𝚕𝚎𝚡| obtained by sorting lexicographically the characters of . We store with a wavelet tree supporting rank and select operations in O(logσ) time.

  4. (4)

    Let and be the permutations of [|𝚜𝚝-𝚕𝚎𝚡|] defined as follows. For any integers i,j,k, if [i]=a is the k-th occurrence of a in and [i]=a is the k-th occurrence of a in , then (i)=j and (j)=i (note that =1). and can be evaluated in O(logσ) time with O(1) rank and select operations on and .

Definition 16.

We denote with 𝚜𝚝-𝚕𝚎𝚡 the permutation of 𝚜𝚝-𝚕𝚎𝚡 defined as follows: for any j[|𝚜𝚝-𝚕𝚎𝚡|], 𝚜𝚝-𝚕𝚎𝚡[j]=𝚜𝚝-𝚕𝚎𝚡[(j)] or, equivalently (since and are inverse of each other), 𝚜𝚝-𝚕𝚎𝚡[j]=𝚜𝚝-𝚕𝚎𝚡[(j)].

We store one Range Minimum and one Range Maximum data structure on the array π(𝚜𝚝-𝚕𝚎𝚡), supporting queries in constant time in O(|𝚜𝚝-𝚕𝚎𝚡|) bits of space (we do not need to store 𝚜𝚝-𝚕𝚎𝚡 explicitly).

 Remark 17.

While this is not fundamental for our discussion below, it may be helpful from an intuitive point of view to observe that string , once removed character # from it, is a subsequence of length |𝚜𝚝-𝚕𝚎𝚡|1 of the colexicographic Burrows-Wheeler transform (BWT). Similarly, permutations and are the counterpart of functions LF and FL typically used with the BWT.

2.1.2 Node representation

Suffix tree navigation operations are supported on a particular representation of (explicit) suffix tree nodes that we describe next. First, Lemma 13 immediately implies:

Corollary 18.

Let u be an explicit suffix tree node and α be such that u=locus(α). Then, α suffixes 𝒯[1,j] for at least one value j𝚜𝚝-𝚕𝚎𝚡.

In the Following, we describe our representation of suffix tree nodes.

Definition 19 (Suffix tree node representation).

We represent suffix tree node u=locus(α) with the tuple of integers

Ru=(b,e,imin,imax,|α|), where 
  • 𝚜𝚝-𝚕𝚎𝚡[b,e] is the colexicographic range of α in 𝚜𝚝-𝚕𝚎𝚡 (by Corollary 18, eb always holds);

  • 𝒯[imin,imin+|α|1]=α is the occurrence of α minimizing π(imin), that is, 𝒯[imin,n] is the lexicographically-smallest suffix prefixed by α;

  • 𝒯[imax,imax+|α|1]=α is the occurrence of α maximizing π(imax), that is, 𝒯[imax,n] is the lexicographically-largest suffix prefixed by α; and

  • |α| is the string depth of u.

 Remark 20.

Observe that n𝚜𝚝-𝚕𝚎𝚡[1,2]. In particular, if 1𝚜𝚝-𝚕𝚎𝚡𝚜𝚝-𝚕𝚎𝚡+ then 0𝚜𝚝-𝚕𝚎𝚡. Since 0 corresponds to the text’s prefix 𝒯[1,0] (the empty string), in this case 𝚜𝚝-𝚕𝚎𝚡[1]=0 because the empty string is smaller than any other text prefix. In that case, 𝚜𝚝-𝚕𝚎𝚡[2]=n because 𝒯[1,n] (ending with $) is the second colexicographically-smallest sampled prefix. If, on the other hand, 1𝚜𝚝-𝚕𝚎𝚡𝚜𝚝-𝚕𝚎𝚡+, then 𝚜𝚝-𝚕𝚎𝚡[1]=n.

Based on the above remark:

Definition 21.

We denote with i{1,2} the integer such that 𝚜𝚝-𝚕𝚎𝚡[i]=n.

Letting u be a leaf, observe that α(u) ends with character $. It follows that the colexicographic range of α(u) in 𝚜𝚝-𝚕𝚎𝚡 is 𝚜𝚝-𝚕𝚎𝚡[i,i]. This will be used later.

2.1.3 Suffix tree operations

Next, we show how to support a useful subset of suffix tree operations on our data structure. This will prove Theorem 2. In the description below, suffix tree operations will take as input node representations (Ru) instead of nodes themselves (u). Recall that we are assuming we have access to a text oracle supporting longest common extension (lce) and random access queries on 𝒯 in O(t) time and fingerprinting queries in O(h) time.

Root.

Let u=locus(ϵ) be the suffix tree root. 𝑟𝑜𝑜𝑡() returns Ru=(1,|𝚜𝚝-𝚕𝚎𝚡|,imin,imax,0) in O(1) time, where 𝒯[imin,n] is the lexicographically-smallest text suffix and 𝒯[imax,n] is the lexicographically-largest text suffix (in other words, imin=SA[1]=n and imax=SA[n]).

String depth.

Let Ru=(b,e,imin,imax,). Then, 𝑠𝑑𝑒𝑝𝑡ℎ(Ru) returns in O(1) time.

Ancestor

Let Ru=(b,e,imin,imax,) and Ru=(b,e,imin,imax,). If >, u cannot be an ancestor of u so 𝑎𝑛𝑐𝑒𝑠𝑡𝑜𝑟(Ru,Ru) returns false. Otherwise, 𝑎𝑛𝑐𝑒𝑠𝑡𝑜𝑟(Ru,Ru) returns true if and only if rlce(imin,imin), that is, if and only if the string α=𝒯[imin,imin+1] with u=locus(α) is a prefix of α=𝒯[imin,imin+1] with u=locus(α). This operation runs in O(t) time.

Is leaf.

Let Ru=(b,e,imin,imax,). Then, 𝑖𝑠𝑙𝑒𝑎𝑓(Ru) returns true (in O(1) time) if and only if imin=imax, if and only if b=e=i (see Definition 21), if and only if the string α=𝒯[imin,imin+1] with u=locus(α) ends with $, that is, imin+1=n (equivalently, 𝒯[imin+1]=$).

Locate leaf.

Let Ru=(b,e,imin,imax,). The output of 𝑙𝑜𝑐𝑎𝑡𝑒(Ru) is defined only if 𝑖𝑠𝑙𝑒𝑎𝑓(Ru) is true. In that case, 𝑙𝑜𝑐𝑎𝑡𝑒(Ru) returns imin (=imax) in O(1) time.

Leftmost/rightmost leaves.

Let Ru=(b,e,imin,imax,). Then, in O(1) time we can compute 𝑙𝑙𝑒𝑎𝑓(Ru)=(i,i,imin,imin,nimin+1) and 𝑟𝑙𝑒𝑎𝑓(Ru)=(i,i,imax,imax,nimax+1).

Edge label.

Let (u,u) be a suffix tree edge, with Ru=(b,e,imin,imax,) and Ru=(b,e,imin,imax,). Then, 𝑙𝑎𝑏𝑒𝑙(Ru,Ru) returns (imin+,imin+1) in O(1) time.

Next leaf.

Nishimoto and Tabei [41] showed that, starting from i[n], k consecutive applications ϕ¯(i),ϕ¯2(i),,ϕ¯k(i) of the permutation defined below111This permutation is usually denoted as ϕ1. Here we instead use the symbol ϕ¯. can be computed in O(loglog(n/r)+k) time with a data structure using O(r) words of space.

Definition 22 (ϕ-function).

Let ϕ¯:[n][n] be defined as

ϕ¯(i)={SA[ISA[i]+1]if ISA[i]<n,SA[1]if ISA[i]=n.

Observe that, by the definition of ϕ¯, leaf locus(𝒯[ϕ¯(i),n]) is the next leaf in lexicographic order after leaf locus(𝒯[i,n]) (unless the latter is the suffix tree’s rightmost leaf).

Let u be a leaf, with Ru=(i,i,i,i,ni+1) (see Definition 21 for the definition of i). Then, unless u is the rightmost leaf, next(Ru)=(i,i,ϕ¯(i),ϕ¯(i),nϕ¯(i)+1). It follows that the structure of Nishimoto and Tabei can be used to evaluate k consecutive applications of 𝑛𝑒𝑥𝑡() in O(loglog(n/r)+k) time.

Smallest children label and successor child.

Let u be a node with Ru=(b,e,imin,imax,). Operation 𝑓𝑖𝑟𝑠𝑡(Ru) returns the alphabetically-smallest label in [b,e] (i.e., in out(u)). Operation succ(Ru,a) returns the alphabetically-smallest label in [b,e] (out(u)) being larger than a. Both queries reduce to an orthogonal range successor (also known as range next value) query in the range [b,e], an operation that can be solved in O(logσ) time on wavelet trees [37]. In both queries, if #[b,e] then we simply ignore it.

Child by letter.

The function 𝑐ℎ𝑖𝑙𝑑(Ru,a) is the most technically-interesting operation. Let u be a node with Ru=(b,e,imin,imax,) and aΣ be a letter. Let α=𝒯[imin,imin+1] be such that u=locus(α). Lemma 13 implies the following corollary:

Corollary 23.

Let u=locus(α), and let 𝚜𝚝-𝚕𝚎𝚡[b,e] be the range containing the text positions j𝚜𝚝-𝚕𝚎𝚡 such that 𝒯[1,j] is suffixed by α. All (and only) the letters labeling the outgoing edges from node u appear in [b,e]{#}, that is, out(u)={c:c[b,e]c#}.

Following Corollary 23, if a[b,e] (a test taking O(logσ) time using rank and select operations on ), then we can return 𝑐ℎ𝑖𝑙𝑑(Ru,a)=(0,0,0,0,0), signaling that no outgoing edge from u is labeled with a.

Otherwise, we first show how to compute imin and imax such that 𝒯[imin,n] and 𝒯[imax,n] are the lexicographically-smallest and lexicographically-largest suffixes being prefixed by αa, respectively. After that, we show how to use this information to compute 𝑐ℎ𝑖𝑙𝑑(Ru,a).

Due to space constraints, we provide only the outlines here. The detailed description can be found in the full version [4].

Observe that |out(u)|2, since u is an explicit suffix tree node. We distinguish three cases. (i) a is neither the alphabetically-largest nor the alphabetically-smallest label in [b,e]{#}, i.e. amin{c[b,e]{#}} and amax{c[b,e]{#}} hold; (ii) a is the alphabetically-smallest label in [b,e]{#}, i.e., a=min{c[b,e]{#}}; (iii) a is the alphabetically-largest label in [b,e]{#}, i.e., a=max{c[b,e]{#}}.

To simplify the discussion below, we rephrase Lemma 13 to the particular STPDs we are using in this section (i.e. those derived from π=ISA and π¯[i]=nISA[i]+1):

Corollary 24.

Let α be right-maximal, and let 𝚜𝚝-𝚕𝚎𝚡[b,e] be the range containing the text positions i𝚜𝚝-𝚕𝚎𝚡 such that 𝒯[1,i] is suffixed by α. Let moreover C={cΣ:αcoccursin𝒯} be the set of all the characters extending α in the text. Then:

  1. (a)

    Let c(CminC), and let 𝒯[j|α|+1,n] be the lexicographically-smallest suffix being prefixed by αc=𝒯[j|α|+1,j+1]. Then, j𝚜𝚝-𝚕𝚎𝚡[b,e].

  2. (b)

    Let c(CmaxC), and let 𝒯[j|α|+1,n] be the lexicographically-largest suffix being prefixed by αc=𝒯[j|α|+1,j+1]. Then, j𝚜𝚝-𝚕𝚎𝚡[b,e].

We now show how to compute imin and imax. The three cases are considered as follows:

  1. (i)

    By Corollary 24, imin′′,imax′′𝚜𝚝-𝚕𝚎𝚡[b,e], where 𝒯[imin′′+1,n] and 𝒯[imax′′+1,n] are the lexicographically smallest and largest suffixes being prefixed by αa, respectively. We locate the leftmost and rightmost occurrences of letter a in [b,e] using rank/select operations on , in O(logσ) time. We apply to locate corresponding a’s in . Range minimum/maximum queries in range π(𝚜𝚝-𝚕𝚎𝚡)[b,e] followed by applying , imin′′ and imax′′ can be retrieved. Then we obtain imin=imin′′+1 and imax=imax′′+1.

  2. (ii)

    We can find imax′′ following the same procedure described in (i) above (resorting to Range Maximum Queries). And since 𝒯[imin,n] is the lexicographically-smallest suffix being prefixed by αa, we have imin=imin and imax=imax′′+1.

  3. (iii)

    Symmetric to (ii).

If imin=imax, 𝑐ℎ𝑖𝑙𝑑(Ru,a) is a leaf, thus we simply return the tuple 𝑐ℎ𝑖𝑙𝑑(Ru,a)=(i,i,imax,imax,nimax+1). If iminimax (i.e., 𝑐ℎ𝑖𝑙𝑑(Ru,a) is not a leaf), note that =rlce(imin,imax) is the string depth of 𝑐ℎ𝑖𝑙𝑑(u,a). In particular, 𝑐ℎ𝑖𝑙𝑑(u,a)=locus(α), where α=𝒯[imin,imin+1].

Simple binary search can compute [b′′,e′′] such that for all j[b′′,e′′], α is a suffix of 𝒯[1,𝚜𝚝-𝚕𝚎𝚡[j]], with O(log|𝚜𝚝-𝚕𝚎𝚡|) random access queries. If the text oracle supports lce queries in O(t) time, this process can be done in time O(tlog|𝚜𝚝-𝚕𝚎𝚡|)O(tlogr). With z-fast tries [5, 9] on {𝒯[1,𝚜𝚝-𝚕𝚎𝚡[i]]:i[|𝚜𝚝-𝚕𝚎𝚡|]}, we can find [b′′,e′′] in O(hlogn) time (I/O operations, resp.) where O(h) is the time (I/O complexity, resp.) for fingerprinting.

We finally have all ingredients to return our result: 𝑐ℎ𝑖𝑙𝑑(Ru,a)=(b′′,e′′,imin,imax,).

Putting everything together.

To sum up, our data structure uses O(|𝚜𝚝-𝚕𝚎𝚡|+r)=O(r) space on top of the text oracle. Taking into account the complexity of all queries discussed above, this proves Theorem 2. By plugging the random access oracle in [42], we obtain: See 3

2.2 General locating mechanism for order-preserving STPDs

In this subsection we provide a general locating mechanism working on any order-preserving STPD. First, we show how to locate the pattern occurrence P=𝒯[i,j] minimizing π(i) among all pattern occurrences. We call this occurrence primary. Then we show that, starting from the (unique) primary occurrence, we can locate the remaining ones (called secondary) by resorting to orthogonal point enclosure. As a matter of fact, this technique generalizes the r-index’ ϕ function (Definition 22, cases π=ISA and π=IPA) to arbitrary order-preserving permutations. This increased generality with respect to Section 2.1, comes at the price of not being able to support suffix tree queries (only pattern matching).

After this section, we will tackle the particular case π=IPA (colexicographic order of the text’s prefixes), for which the locating algorithm that we describe here can be simplified. That particular case will lead to our optimized implementation able to beat the r-index both in query time (by orders of magnitude) and space usage.

For the remainder of the section, we assume 𝒯Σn is a text and π is any order-preserving permutation on 𝒯. We start by classifying the occurrences of a pattern PΣ+ as follows.

Definition 25 (Primary/Secondary occurrence).

For a string PΣ+, an occurrence 𝒯[i,i+|P|1]=P is said to be a primary occurrence if and only if LPFπ[i]<|P|. All the other occurrences are called secondary occurrences.

Lemma 26.

For any string PΣ+ that occurs in 𝒯 there exists exactly one primary occurrence P=𝒯[i,i+|P|1]. Furthermore, such occurrence is the one minimizing π(i).

2.2.1 Finding the primary occurrence

The idea to locate the primary pattern occurrence is simple and can be visualized as a process of walking along the paths of the STPD, starting from the root. Whenever we find a mismatch between the pattern P and the current STPD path, we change path by running a suffix search (e.g. binary search) on PDAπ. We first provide an intuition through an example (Example 27). Our algorithm is formalized in Algorithm 1. Then, we prove the algorithm’s complexity, correctness, and completeness.

Example 27.

Consider the STPD of Figure 1, and let P=CGCGAA be the query pattern. We start by matching P with the characters of the path 𝒯[11,11]=$ starting at the root. The longest pattern prefix matching the path is ϵ (the empty string). To continue matching P, we need to change path. We binary search PDAπ=𝚜𝚝-𝚕𝚎𝚡 looking for a sampled text prefix being suffixed by ϵP[1]=C (i.e. the concatenation of the pattern’s prefix matched so far and the first unmatched pattern’s character). Two sampled prefixes (elements in 𝚜𝚝-𝚕𝚎𝚡) satisfy this requirement: 𝒯[1,3] and 𝒯[1,7]. By definition of our STPD, among them we need to choose the one 𝒯[1,i] minimizing π(i)=ISA[i]. This choice can be performed in constant time with the aid of a Range Minimum Query data structure built on top of π(𝚜𝚝-𝚕𝚎𝚡). Such prefix minimizing π(i) is 𝒯[1,7]. This means that we choose an STPD path labeled with 𝒯[7,11]. Observe that this also means that 𝒯[7] is the lexicographically-smallest occurrence of P[1]. We repeat the process, matching the remaining characters P[1,6] of P. As can be seen in Figure 1 characters P[1,2]=CG match (purple path starting below the root). Then, the path continues with A and the pattern with P[3]=C. As done above, we binary search PDAπ=𝚜𝚝-𝚕𝚎𝚡 looking for a sampled text prefix being suffixed by P[1,2]P[3]=CGC. Now, only one sampled prefix matches: 𝒯[1,7], corresponding to an STPD path labeled with 𝒯[7,11]. Observe that this means that 𝒯[7] is the lexicographically-smallest occurrence of P[3] being preceded by P[1,2]; in other words, 𝒯[72,7]=𝒯[5,7] is the lexicographically-smallest occurrence of P[1,3]. We therefore continue matching the remaining pattern’s suffix P[3,6] on 𝒯[7,11]. This time, the whole pattern’s suffix matches, hence we are done. Since the last binary search returned the sampled text’s prefix 𝒯[1,7], and before running the search we already matched P[1,2], we return pattern occurrence 𝒯[72,(72)+|P|1]=𝒯[5,10] which, by construction of our STPD and by the order-preserving property of π, is the lexicographically-smallest one (in this example, also the only one).

Data structures and search algorithm.

We show that, interestingly, a small modification of the search algorithm of Suffixient Arrays [10] (see Appendix A in the full version [4]) allows locating the primary pattern occurrence on any order-preserving STPD. The search algorithm is sketched in Example 27 and formalized in Algorithm 1. We need the following data structures:

  1. (i)

    A Range Minimum Data structure on π(PDAπ), requiring just O(|PDAπ|) bits and answering queries in constant time. In Algorithm 1, this data structure allows finding the argmin at Line 6 in constant time.

  2. (ii)

    A data structure supporting suffix searches on the text’s prefixes {𝒯[1,PDAπ[t]]:t[|PDAπ|]}. Given (i,j,c)[n]×[n]×Σ, sufsearch(i,j,c) returns the maximal range [b,e][|PDAπ|] such that 𝒯[1,PDAπ[t]] is suffixed by 𝒯[i,j]c for all t[b,e]. This structure is used in Line 5 of Algorithm 1. We discuss different possible implementations for this structure below.

  3. (iii)

    A text oracle supporting random access on 𝒯. To speed up sufsearch we may also require the oracle to support lce and/or fingerprinting queries on 𝒯 (we obtain different performance depending on which queries are available, read below).

Algorithm 1 Locating the primary pattern occurrence.
Complexity.

As observed above, the argmin operation in Line 6 takes just O(1) time using a Range Minimum data structure built over π(PDAπ). For the analysis of sufsearch(i,j,c), we provide only the summarized result here due to space constraints. The detailed analysis is available in the full version [4]. If we use binary search on PDAπ and a random access oracle on 𝒯 that supports the extraction of contiguous text characters with O(1+/B) I/O complexity, then sufsearch(i,j,c) can be solved with O((1+m/B)logn) I/O complexity. If the random access oracle supports llce, this can be done in O(tlog|PDAπ|)O(tlogn) time (respectively, I/O complexity), where t is the time complexity (respectively, I/O complexity) of llce and random access queries. With z-fast tries [5, 9] built on the text prefixes {𝒯[1,i1]:iPDAπ𝒯[i]=c} for each cΣ, we obtain the following:

Lemma 28.

Let 𝒯Σn be a text and π:[n][n] be an order-preserving permutation. Suppose we have access to an oracle supporting fingerprinting queries on 𝒯 in O(h) time (respectively, I/O complexity) and extraction of contiguous text characters in e() time (respectively, I/O complexity). Then, Algorithm 1 runs in O(dhlogm+e(m)) time (respectively, I/O complexity), where d is the node depth of locus(P) in the suffix tree of 𝒯.

Lemma 29.

Algorithm 1 is correct and complete.

Proof (Sketch).

The invariant maintained by the while loop is: if P occurs in 𝒯, then P[1,j1]=𝒯[ij+1,i1] is the occurrence of P[1,j1] minimizing π(ij+1).

2.2.2 Locating the secondary occurrences

We now describe how to locate the secondary occurrences. This subsection is devoted to proving the following lemma.

Lemma 30.

Let 𝒯Σn be a text and π:[n][n] be an order-preserving permutation. Let PΣm occur in 𝒯. There exists a data structure that takes O(|PDAπ|) words of space and that, given the primary occurrence of P, finds all the occ1 secondary occurrences in O(occlog|PDAπ|)O(occlogn) time (equivalently, I/O complexity).

We start by covering 𝒯 with |PDAπ| (possibly overlapping) phrases (that is, substrings of 𝒯), as follows:

Definition 31 (Phrase cover of 𝒯).
  • (Type-1 phrases) we associate phrase 𝒯[i] (one character) to each position i[n] such that LPFπ[i]=0.

  • (Type-2 phrases) We associate phrase 𝒯[i,i+LPFπ[i]1] to each irreducible LPFπ position i such that LPFπ[i]>0.

Observe that there are at most |PDAπ| type-2 phrases. By definition, our cover of 𝒯 into phrases satisfies the following properties:

 Remark 32.

Any pattern occurrence 𝒯[i,i+m1] crossing a type-1 phrase 𝒯[i] (i.e. i[i,i+m1]) is primary. To see this observe that, due to LPFπ[i]=0, we know that c=𝒯[i] is the occurrence of c minimizing π(i), hence by the order-preserving property of π, 𝒯[i,i+m1]=P is the occurrence of P minimizing π(i).

 Remark 33.

For each secondary occurrence 𝒯[i,i+m1], there exists a type-2 phrase 𝒯[i,i+LPFπ[i]1] containing it, i.e. [i,i+m1][i,i+LPFπ[i]1]. This immediately follows from the definition of secondary occurrence.

Observe that each type-2 phrase is copied from another text position with a smaller π. We formalize this fact as follows:

Definition 34 (Phrase source).

Let 𝒯[i,i+LPFπ[i]1] be a type-2 phrase. We define SRC[i]=j to be any position j with π(j)<π(i) and 𝒯[i,i+LPFπ[i]1]=𝒯[j,j+LPFπ[i]1].

We also use the fact that each phrase can be split into a prefix containing strictly decreasing LPFπ values and the remaining suffix. This will play a crucial role in our locating algorithm, as it will allow us to report each secondary occurrence exactly once.

Definition 35 (Reducible prefix).

Let 𝒯[i,i+LPFπ[i]1] be a type-2 phrase. The reducible prefix of 𝒯[i,i+LPFπ[i]1] is its longest prefix 𝒯[i,i+i1], with 1iLPFπ[i], such that LPFπ[j]=LPFπ[j1]1 for each j[i+1,i+i1].

 Remark 36.

All LPFπ positions in [i+1,i+i1] are reducible (that is, not irreducible).

Figure 2: Consider this particular string 𝒯 and take π=id to be the identity function. Then, LPFπ=LPF is the classic Longest Previous Factor array. In the third line, we put in boxes the irreducible LPF positions i such that LPF[i]>0; these are the beginnings of our phrases (7 phrases in total). In Lines I1I7 in the figure, we show each type-2 phrase’s source as an interval containing the phrase’s positions, colored according to its reducible prefix (in blue) and the remaining suffix (in red). Boxes show how the occurrences of string ba intersect the phrases’ sources; the box is blue when the occurrence intersects (the source of) the phrase’s reducible prefix, red otherwise. Only occurrences in a blue box trigger the location of further secondary occurrences.

The idea to locate secondary occurrences, is to associate every type-2 phrase 𝒯[i,i+LPFπ[i]1] with a 2-dimensional rectangle whose coordinates reflect the source of the whole phrase and of its reducible prefix:

Definition 37 (Rectangle associated with a type-2 phrase).

Let 𝒯[i,i+LPFπ[i]1] be a type-2 phrase, si=SRC[i] be its source, and i be the length of its reducible prefix. We associate with 𝒯[i,i+LPFπ[i]1] the 2-dimensional rectangle [si,si+i1]×[si,si+LPFπ[i]1][n]2, and label it with position i.

Example 38.

In the running example of Figure 2, consider the phrase 𝒯[9,14], let s9=SRC[9]=6 be its source, and 9=5 be the length of its reducible prefix. This phrase is associated with rectangle [s9,s9+91]×[s9,s9+LPF[9]1]=[6,10]×[6,11].

Our locating algorithm relies on the following well-known data structure result on the orthogonal point enclosure problem:

Lemma 39 (Orthogonal point enclosure, [11, Theorem 6]).

Let be a collection of axis-parallel two-dimensional rectangles in [n]2. There exists an O(||)-space data structure supporting the following query: given a point (x,y), find all rectangles [a,b]×[c,d] containing (x,y), i.e. such that x[a,b] and y[c,d]. The query is answered in O(log||+k) time, where k is the number of returned rectangles.

Let be the set of rectangles in Definition 37. As noted above, |||PDAπ|. We build the data structure of Lemma 39 on . The structure uses O(|PDAπ|) words of space and answers orthogonal point enclosure queries in O(log|PDAπ|+k)O(logn+k) time.

Locating algorithm.

Let 𝒯[j,j+m1]=P be the primary occurrence of P, found with Algorithm 1. To locate the secondary occurrences, initialize a stack Q{j}. While Q is not empty:

  1. 1.

    Pop an element x from Q and report pattern occurrence x.

  2. 2.

    Locate all rectangles in containing point (x,x+m1). For each retrieved rectangle [si,si+i1]×[si,si+LPFπ[i]1] labeled with position i, push i+xsi in Q.

Analysis.

Due to space constraints, we defer the detailed analysis to the full version [4]. The time complexity can be derived from the observation that no occurrence is pushed more than once into the stack. Combining this with Lemmas 28, 29, and 30 we obtain:

Theorem 40.

Let 𝒯Σn be a text and π:[n][n] be an order-preserving permutation. Suppose we have access to an oracle supporting fingerprinting queries on 𝒯 in O(h) time (respectively, I/O complexity) and the extraction of contiguous characters of 𝒯 in e() time (respectively, I/O complexity). Then, there exists a data structure taking O(|PDAπ|) words of space on top of the oracle and able to report the occ occurrences of any pattern PΣm in O(dhlogm+e(m)+occlog|PDAπ|)O(dhlogm+e(m)+occlogn) time (respectively, I/O complexity), where d is the node depth of locus(P) in the suffix tree of 𝒯.

For example, using the text oracle of Prezza [42], the I/O complexity of Theorem 40 becomes O(dlogm+m/B+occlogn). The resulting index uses O(|PDAπ|) memory words on top of the oracle of nlogσ+O(logn) bits.

2.3 Colexicographic rank (𝚜𝚝-𝚌𝚘𝚕𝚎𝚡): smaller-space I/O-efficient pattern matching

We now move to the particular case π=IPA, for which the algorithm described in the previous section can be simplified, leading to a very space-efficient and fast implementation.

Figure 3 depicts the STPD obtained by choosing π=IPA to be the Inverse Prefix Array. We denote with 𝚜𝚝-𝚌𝚘𝚕𝚎𝚡=PDAπ the path decomposition array associated with this permutation π. Similarly, 𝚜𝚝-𝚌𝚘𝚕𝚎𝚡+ denotes the path decomposition array associated with the dual permutation π¯(i)=nIPA[i]+1. The following properties hold:

Lemma 41.

Let 𝒯Σn be a text. The permutations π,π¯ defined as π(i)=IPA[i] and π¯(i)=nIPA[i]+1 for i[n] are order-preserving for 𝒯. Furthermore, |𝚜𝚝-𝚌𝚘𝚕𝚎𝚡|r¯ and |𝚜𝚝-𝚌𝚘𝚕𝚎𝚡+|r¯ hold.

Figure 3: Example of the STPD obtained by taking π=IPA=[2,3,6,9,7,10,8,11,5,4,1]. Paths 𝒯[j,n] are colored according to the color of j𝚜𝚝-𝚌𝚘𝚕𝚎𝚡.

We now show how to locate the pattern’s occurrences with 𝚜𝚝-𝚌𝚘𝚕𝚎𝚡. In this section, we assume a text oracle supporting the extraction of contiguous text characters with O(1+/B) I/O complexity.

2.3.1 Finding the primary occurrence

For the particular order-preserving permutation π=IPA used in this section, the primary occurrence P=𝒯[i,j] of P is the one for which the text prefix 𝒯[1,j] is the colexicographically-smallest being suffixed by P.

We use Algorithm 1 to locate the primary occurrence. Since π=IPA (colexicographic rank) and PDAπ=𝚜𝚝-𝚌𝚘𝚕𝚎𝚡 is sorted colexicographically, observe that π(PDAπ)=π(𝚜𝚝-𝚌𝚘𝚕𝚎𝚡) is increasing. This means that, in Line 6 of Algorithm 1, it always holds argmini[b,e]{π(PDAπ[i])}=b and therefore we do not need a Range Minimum Data structure over π(𝚜𝚝-𝚌𝚘𝚕𝚎𝚡).

By implementing sufsearch() by binary search and random access, we obtain:

Lemma 42.

Let 𝒯Σn be a text, and fix π=IPA. Suppose we have a text oracle supporting extraction of contiguous characters with O(1+/B) I/O complexity. Algorithm 1 requires just array 𝚜𝚝-𝚌𝚘𝚕𝚎𝚡, fitting in |𝚜𝚝-𝚌𝚘𝚕𝚎𝚡|r¯ words, on top of the text oracle and locates the primary occurrence of PΣm with O(dlog|𝚜𝚝-𝚌𝚘𝚕𝚎𝚡|(1+m/B))O(dlogr¯(1+m/B)) I/O complexity, where d is the node depth of locus(P) in the suffix tree of 𝒯.

2.3.2 Locating the secondary occurrences

Due to space constraints, here we describe only the outlines of how to locate secondary occurrences. The full description can be found in the full version [4]. Briefly speaking, we can exploit the locating mechanism of the r-index [21], with minor modifications. Differently from the toehold lemma of the r-index, Algorithm 1 only allows to compute PA[b] (not occ). If we use both 𝚜𝚝-𝚌𝚘𝚕𝚎𝚡 and 𝚜𝚝-𝚌𝚘𝚕𝚎𝚡+, we can apply ϕ¯ repeatedly starting from the primary occurrence for 𝚜𝚝-𝚌𝚘𝚕𝚎𝚡 until we reach that for 𝚜𝚝-𝚌𝚘𝚕𝚎𝚡+, this will be exactly occ1 applications of ϕ¯. On the other hand, we can compute the number occurrences using just 𝚜𝚝-𝚌𝚘𝚕𝚎𝚡. We can find i1 such that (i1)m/Bocc<im/B by applying ϕ¯ recursively and comparing the text with the pattern for every m/B applications. Then, we perform binary search to find occ. As far as the I/O complexity is concerned, the cost of the first phase is O((1+occ/m/B)(1+m/B))O(1+occ+m/B), and that of the second binary search phase is O((1+m/B)logm/B)O((1+m/B)log(1+m/B)).

2.3.3 Putting everything together

Locating the occ1 secondary occurrences of P costs O((1+m/B)log(1+m/B)+occ) I/O complexity and requires O(1+m/B) words of memory on top of the index at query time. Combining this with Lemma 42, we obtain:

Theorem 43.

Let 𝒯Σn be a text. Assume we have access to a text oracle supporting the extraction of contiguous characters of 𝒯 with O(1+/B) I/O complexity. Our data structure locates all the occ occurrences of PΣm with I/O complexity

O((dlogr¯+log(1+m/B))(1+m/B)+occ+loglog(n/r¯))

and uses O(r¯) memory words on top of the oracle. At query time, O(m/B) further memory words are used.

Observe that the extra O(m/B) memory words of space are negligible; most compressed indexes explicitly store (and/or receive as input) the full pattern at query time anyways, in O(m) words. The remaining O(r¯) words of space are spent to store array 𝚜𝚝-𝚌𝚘𝚕𝚎𝚡 (at most |𝚜𝚝-𝚌𝚘𝚕𝚎𝚡|r¯ words) and Nishimoto and Tabei’s data structure [41] storing function ϕ¯ (less than 2r¯ words using the optimized implementation of [7]).

2.4 Identity (𝚜𝚝-𝚙𝚘𝚜): leftmost pattern occurrence

Another notable STPD is obtained by using the identity function π(i)=i, trivially satisfying the order-preserving property of Definition 5. We call the corresponding path decomposition array 𝚜𝚝-𝚙𝚘𝚜. Similarly, 𝚜𝚝-𝚙𝚘𝚜+ is the path decomposition array associated with the dual permutation π¯(i)=ni+1.

The size of 𝚜𝚝-𝚙𝚘𝚜 is equal to the number of irreducible values in the Longest Previous Factor array LPF, a new interesting repetitiveness measure that, to the best of our knowledge, has never been studied before. While we could not prove a theoretical bound for |𝚜𝚝-𝚙𝚘𝚜| and |𝚜𝚝-𝚙𝚘𝚜+| in term of known repetitiveness measures, below we show that these measures are worst-case optimal, meaning that for every p1 we exhibit a family of strings with p=Θ(|𝚜𝚝-𝚙𝚘𝚜|) requiring O(p) words to be stored in the worst case.

Theorem 44.

For any integers n1 and p[n], there exists a family of (np) strings over an alphabet of size p+1 such that for every string 𝒮 it holds that |𝚜𝚝-𝚙𝚘𝚜(𝒮)|=p+1 and |𝒮|np. In particular, no compressor can compress every individual 𝒮 in asymptotically less than log2(np)=plog(n/p)+Θ(p) bits. The same holds for |𝚜𝚝-𝚙𝚘𝚜+|.

Proof (Sketch).

Consider any integer set {x1>x2>>xp}[n]. Encode the set as the string 𝒮=0x110x220xpp. Then |𝚜𝚝-𝚙𝚘𝚜(𝒮)|=p+1. Fix n1 and p[n]. Then, the family n,p of such strings contains (np) elements. The proof for 𝚜𝚝-𝚙𝚘𝚜+ is symmetric.

Theorem 44 proves that p=Θ(|𝚜𝚝-𝚙𝚘𝚜|) words of space are essentially worst-case optimal as a function of n and p to compress the string (the same holds for p=|𝚜𝚝-𝚙𝚘𝚜+|). This result is similar to that obtained in [28] for the repetitiveness measure δ. Since by Theorem 14, O(|𝚜𝚝-𝚙𝚘𝚜|log|𝒮|) bits (in the theorem above, O(plog(np))=O(plogn) bits) are also sufficient to compress 𝒮 (the same holds for |𝚜𝚝-𝚙𝚘𝚜+|), this indicates that |𝚜𝚝-𝚙𝚘𝚜| and |𝚜𝚝-𝚙𝚘𝚜+| are two meaningful repetitiveness measures.

We conclude this section with the following discussion. More detailed explanations can be found in the full version [4].

  • Application to taxonomic classification of DNA fragments. The taxonomic classifiers Kraken [50] and Kraken 2 [49] index the genomes in a given phylogenetic tree such that, given a pattern, they can map each substring of fixed length k to the root of the smallest subtree of the phylogenetic tree containing all the genomes containing that substring. A bottleneck is finding the leftmost and rightmost such genomes, which can now be efficiently done using our 𝚜𝚝-𝚙𝚘𝚜 and 𝚜𝚝-𝚙𝚘𝚜+.

  • Relation to Ukkonen’s suffix tree construction algorithm. Ukkonen’s algorithm [47] builds the suffix tree by inserting the suffixes from the longest (𝒯[1,n]) to the shortest (𝒯[n,n]). Instead of inserting exactly one suffix (leaf) per iteration like McCreight’s algorithm [36], it inserts a variable number (possibly none) of leaf nodes per iteration. |𝚜𝚝-𝚙𝚘𝚜| can be interpreted as the number of iterations that insert at least one leaf.

  • Relation with PPM. Prediction by Partial Matching with unbounded context (PPM) is a popular and effective compression algorithm that encodes each text’s symbol 𝒯[j]=c according to the probability distribution of characters following the longest context 𝒯[i,j1]=α preceding it that already occurred before in the text followed by c. In the simple version of PPM [15], when all previous occurrences of α are never followed by c, the algorithm outputs a special escape symbol followed by character c. Then, |𝚜𝚝-𝚙𝚘𝚜| is upper-bounded by the number of occurrences of output by this algorithm.

3 Preliminary experimental results

Comparison with other repetitiveness measures.

Table 1 compares the sizes (number of samples) of the three notable suffix tree path decompositions discussed in this paper with existing repetitiveness measures on three repetitive datasets downloaded from https://pizzachili.dcc.uchile.cl/repcorpus.html. Interestingly, on these datasets our new repetitiveness measures are consistently smaller than the smallest suffixient set size (χ) and the number of runs in the Burrows-Wheeler transform of the text (r) and its reverse (r¯).

Table 1: Experimental evaluation of Path Decomposition Array sizes on repetitive strings. All numbers are in millions.
Data n |𝚜𝚝-𝚕𝚎𝚡| |𝚜𝚝-𝚌𝚘𝚕𝚎𝚡| |𝚜𝚝-𝚙𝚘𝚜| χ r r¯
Influenza 154.808 1.815 1.805 01.928 02.225 03.022 03.018
Cere 461.286 7.455 7.455 08.954 09.921 11.574 11.575
Escherichia 112.689 9.817 9.825 11.677 13.119 15.044 15.045
Compressed index.

We implemented an optimized prototype of our 𝚜𝚝-𝚌𝚘𝚕𝚎𝚡 index (Section 2.3) in C++ to evaluate its performance against the state-of-the-art: the r-index [21], move-r [7], the suffixient array [10] and the suffix array. We used an ad-hoc implementation of Relative Lempel Ziv [30] for the random access oracle in our index. The evaluation focused on space usage and the efficiency of locating one or all pattern occurrences in repetitive genomic data. See the full version of this paper [4] for the detailed implementation choices and experimental results.

Experiments were conducted on an Intel(R) Xeon(R) W-2245 CPU @ 3.90GHz workstation with 8 cores and 128 gigabytes of RAM running Ubuntu 18.04 LTS 64-bit. The input text consisted of 19 variants of Human chromosome 19 (total length n109) downloaded from https://github.com/koeppl/phoni. We extracted 105 patterns of variable length (m=15,150,1500) from random locations in the text. For each pattern, we measured the resources (peak memory and running time) used by all the indexes while finding one pattern occurrence and locating all pattern occurrences.

In our experiments, our st-colex index was always smaller than the r-index, about four times smaller than move-r, and orders of magnitude smaller than the suffix array. It was moreover always slightly smaller than the suffixient array. Our index was always orders of magnitude faster than the r-index on the task of locating one pattern occurrence, and even faster than the suffix array. It was also one order of magnitude faster than move-r on long patterns (m150), and slightly faster on small patterns. As far as locating all pattern occurrences was concerned, we observed similar performance as discussed above for long patterns (m150), due to the small number of reported occurrences per pattern (occ17.2 on average on those pattern lengths). On shorter patterns (m=15), the number of reported pattern occurrences was much larger (occ=6911.6 on average), and, as expected, our index was slightly slower than move-r, slower than the suffix array by an order of magnitude, and slightly faster than the r-index.

References

  • [1] Omar Ahmed, Massimiliano Rossi, Sam Kovaka, Michael C Schatz, Travis Gagie, Christina Boucher, and Ben Langmead. Pan-genomic matching statistics for targeted nanopore sequencing. iScience, 24(6), 2021.
  • [2] Omar Y Ahmed, Massimiliano Rossi, Travis Gagie, Christina Boucher, and Ben Langmead. Spumoni 2: Improved classification using a pangenome index of minimizer digests. Genome Biology, 24(1):122, 2023.
  • [3] Ruben Becker, Davide Cenzato, Travis Gagie, Ragnar Groot Koerkamp, Sung-Hwan Kim, Giovanni Manzini, and Nicola Prezza. STPD-index. Software, Funded by the European Union (ERC, REGINDEX, 101039208), swhId: swh:1:dir:d4f76a2be744c622f98d403443e3f4507ae9b536 (visited on 2026-06-19). URL: https://github.com/regindex/STPD-index, doi:10.4230/artifacts.26761.
  • [4] Ruben Becker, Davide Cenzato, Travis Gagie, Sung-Hwan Kim, Ragnar Groot Koerkamp, Giovanni Manzini, and Nicola Prezza. Compressing suffix trees by path decompositions. arXiv preprint arXiv.2506.14734, 2025. doi:10.48550/arXiv.2506.14734.
  • [5] Djamal Belazzougui, Paolo Boldi, Rasmus Pagh, and Sebastiano Vigna. Monotone minimal perfect hashing: Searching a sorted table with O(1) accesses. In Claire Mathieu, editor, Proceedings of the Twentieth Annual ACM-SIAM Symposium on Discrete Algorithms, SODA 2009, New York, NY, USA, January 4-6, 2009, pages 785–794. SIAM, 2009. doi:10.1137/1.9781611973068.86.
  • [6] Djamal Belazzougui, Manuel Cáceres, Travis Gagie, Pawel Gawrychowski, Juha Kärkkäinen, Gonzalo Navarro, Alberto Ordóñez Pereira, Simon J. Puglisi, and Yasuo Tabei. Block trees. J. Comput. Syst. Sci., 117:1–22, 2021. doi:10.1016/j.jcss.2020.11.002.
  • [7] Nico Bertram, Johannes Fischer, and Lukas Nalbach. Move-r: Optimizing the r-index. In Leo Liberti, editor, 22nd International Symposium on Experimental Algorithms, SEA 2024, Vienna, Austria, July 23-26, 2024, volume 301 of LIPIcs, pages 1:1–1:19. Schloss Dagstuhl – Leibniz-Zentrum für Informatik, 2024. doi:10.4230/LIPIcs.SEA.2024.1.
  • [8] Philip Bille, Gad M. Landau, Rajeev Raman, Kunihiko Sadakane, Srinivasa Rao Satti, and Oren Weimann. Random access to grammar-compressed strings and trees. SIAM J. Comput., 44(3):513–539, 2015. doi:10.1137/130936889.
  • [9] Paolo Boldi and Sebastiano Vigna. Kings, name days, lazy servants and magic. In Hiro Ito, Stefano Leonardi, Linda Pagli, and Giuseppe Prencipe, editors, 9th International Conference on Fun with Algorithms, FUN 2018, La Maddalena, Italy, June 13-15, 2018, volume 100 of LIPIcs, pages 10:1–10:13. Schloss Dagstuhl – Leibniz-Zentrum für Informatik, 2018. doi:10.4230/LIPIcs.FUN.2018.10.
  • [10] Davide Cenzato, Lore Depuydt, Travis Gagie, Sung-Hwan Kim, Giovanni Manzini, Francisco Olivares, and Nicola Prezza. Suffixient arrays: A new efficient suffix array compression technique. arXiv preprint, 2024. arXiv:2407.18753.
  • [11] Bernard Chazelle. Filtering search: A new approach to query-answering. SIAM J. Comput., 15(3):703–724, 1986. doi:10.1137/0215051.
  • [12] Yu-Feng Chien, Wing-Kai Hon, Rahul Shah, and Jeffrey Scott Vitter. Geometric burrows-wheeler transform: Linking range searching and text indexing. In Data Compression Conference (DCC 2008), pages 252–261, 2008. doi:10.1109/DCC.2008.67.
  • [13] Anders Roy Christiansen, Mikko Berggren Ettienne, Tomasz Kociumaka, Gonzalo Navarro, and Nicola Prezza. Optimal-time dictionary-compressed indexes. ACM Trans. Algorithms, 17(1):8:1–8:39, 2021. doi:10.1145/3426473.
  • [14] Francisco Claude and Gonzalo Navarro. Improved grammar-based compressed indexes. In Liliana Calderón-Benavides, Cristina N. González-Caro, Edgar Chávez, and Nivio Ziviani, editors, String Processing and Information Retrieval - 19th International Symposium, SPIRE 2012, Cartagena de Indias, Colombia, October 21-25, 2012. Proceedings, volume 7608 of Lecture Notes in Computer Science, pages 180–192. Springer, 2012. doi:10.1007/978-3-642-34109-0_19.
  • [15] John G. Cleary and W. J. Teahan. Unbounded length contexts for PPM. Comput. J., 40(2/3):67–75, 1997.
  • [16] Davide Cozzi, Massimiliano Rossi, Simone Rubinacci, Travis Gagie, Dominik Köppl, Christina Boucher, and Paola Bonizzoni. μ- PBWT: a lightweight r-indexing of the PBWT for storing and querying UK biobank data. Bioinform., 39(9), 2023. doi:10.1093/bioinformatics/btad552.
  • [17] Vinicius T. V. Date and Leandro M. Zatesko. On the near-tightness of χ2r: A general σ-ary construction and a binary case via LFSRs. arXiv preprint, 2025. arXiv:2512.20598.
  • [18] Paolo Ferragina and Giovanni Manzini. Opportunistic data structures with applications. In 41st Annual Symposium on Foundations of Computer Science, FOCS 2000, Redondo Beach, California, USA, November 12-14, 2000, pages 390–398. IEEE Computer Society, 2000. doi:10.1109/SFCS.2000.892127.
  • [19] Paolo Ferragina and Rossano Venturini. Compressed cache-oblivious string b-tree. ACM Trans. Algorithms, 12(4), August 2016. doi:10.1145/2903141.
  • [20] Travis Gagie, Gonzalo Navarro, and Nicola Prezza. Optimal-time text indexing in BWT-runs bounded space. In Artur Czumaj, editor, Proceedings of the Twenty-Ninth Annual ACM-SIAM Symposium on Discrete Algorithms, SODA 2018, New Orleans, LA, USA, January 7-10, 2018, pages 1459–1477. SIAM, 2018. doi:10.1137/1.9781611975031.96.
  • [21] Travis Gagie, Gonzalo Navarro, and Nicola Prezza. Fully functional suffix trees and optimal text searching in BWT-runs bounded space. J. ACM, 67(1):2:1–2:54, 2020. doi:10.1145/3375890.
  • [22] Gaston H. Gonnet, Ricardo A. Baeza-Yates, and Tim Snider. New indices for text: Pat trees and pat arrays. In William B. Frakes and Ricardo A. Baeza-Yates, editors, Information Retrieval: Data Structures & Algorithms, pages 66–82. Prentice-Hall, 1992.
  • [23] Roberto Grossi and Jeffrey Scott Vitter. Compressed suffix arrays and suffix trees with applications to text indexing and string matching (extended abstract). In F. Frances Yao and Eugene M. Luks, editors, Proceedings of the Thirty-Second Annual ACM Symposium on Theory of Computing, May 21-23, 2000, Portland, OR, USA, pages 397–406. ACM, 2000. doi:10.1145/335305.335351.
  • [24] Juha Kärkkäinen, Giovanni Manzini, and Simon J. Puglisi. Permuted longest-common-prefix array. In Gregory Kucherov and Esko Ukkonen, editors, Combinatorial Pattern Matching, 20th Annual Symposium, CPM 2009, Lille, France, June 22-24, 2009, Proceedings, volume 5577 of Lecture Notes in Computer Science, pages 181–192. Springer, 2009. doi:10.1007/978-3-642-02441-2_17.
  • [25] Dominik Kempa and Tomasz Kociumaka. Resolution of the Burrows-Wheeler transform conjecture. In Sandy Irani, editor, 61st IEEE Annual Symposium on Foundations of Computer Science, FOCS 2020, Durham, NC, USA, November 16-19, 2020, pages 1002–1013. IEEE, 2020. doi:10.1109/FOCS46700.2020.00097.
  • [26] Dominik Kempa and Tomasz Kociumaka. Collapsing the hierarchy of compressed data structures: Suffix arrays in optimal compressed space. In 64th IEEE Annual Symposium on Foundations of Computer Science, FOCS 2023, Santa Cruz, CA, USA, November 6-9, 2023, pages 1877–1886. IEEE, 2023. doi:10.1109/FOCS57990.2023.00114.
  • [27] Dominik Kempa and Nicola Prezza. At the roots of dictionary compression: String attractors. In Ilias Diakonikolas, David Kempe, and Monika Henzinger, editors, Proceedings of the 50th Annual ACM SIGACT Symposium on Theory of Computing, STOC 2018, Los Angeles, CA, USA, June 25-29, 2018, pages 827–840. ACM, 2018. doi:10.1145/3188745.3188814.
  • [28] Tomasz Kociumaka, Gonzalo Navarro, and Nicola Prezza. Toward a definitive compressibility measure for repetitive sequences. IEEE Trans. Inf. Theory, 69(4):2074–2092, 2023. doi:10.1109/TIT.2022.3224382.
  • [29] Sebastian Kreft and Gonzalo Navarro. On compressing and indexing repetitive sequences. Theor. Comput. Sci., 483:115–133, 2013. doi:10.1016/j.tcs.2012.02.006.
  • [30] Shanika Kuruppu, Simon J. Puglisi, and Justin Zobel. Relative Lempel-Ziv compression of genomes for large-scale storage and retrieval. In Edgar Chávez and Stefano Lonardi, editors, String Processing and Information Retrieval - 17th International Symposium, SPIRE 2010, Los Cabos, Mexico, October 11-13, 2010. Proceedings, volume 6393 of Lecture Notes in Computer Science, pages 201–206. Springer, 2010. doi:10.1007/978-3-642-16321-0_20.
  • [31] Abraham Lempel and Jacob Ziv. On the complexity of finite sequences. IEEE Trans. Inf. Theory, 22(1):75–81, 1976. doi:10.1109/TIT.1976.1055501.
  • [32] Veli Mäkinen and Gonzalo Navarro. Succinct suffix arrays based on run-length encoding. Nord. J. Comput., 12(1):40–66, 2005.
  • [33] Veli Mäkinen, Gonzalo Navarro, Jouni Sirén, and Niko Välimäki. Storage and retrieval of highly repetitive sequence collections. J. Comput. Biol., 17(3):281–308, 2010. doi:10.1089/cmb.2009.0169.
  • [34] Udi Manber and Eugene W. Myers. Suffix arrays: A new method for on-line string searches. SIAM J. Comput., 22(5):935–948, 1993. doi:10.1137/0222058.
  • [35] Udi Manber and Gene Myers. Suffix arrays: A new method for on-line string searches. In David S. Johnson, editor, Proceedings of the First Annual ACM-SIAM Symposium on Discrete Algorithms, 22-24 January 1990, San Francisco, California, USA, pages 319–327. SIAM, 1990. URL: http://dl.acm.org/citation.cfm?id=320176.320218.
  • [36] Edward M. McCreight. A space-economical suffix tree construction algorithm. J. ACM, 23(2):262–272, 1976. doi:10.1145/321941.321946.
  • [37] Gonzalo Navarro. Wavelet trees for all. J. Discrete Algorithms, 25:2–20, 2014. doi:10.1016/j.jda.2013.07.004.
  • [38] Gonzalo Navarro. Indexing highly repetitive string collections, part I: Repetitiveness measures. ACM Comput. Surv., 54(2):29:1–29:31, 2022. doi:10.1145/3434399.
  • [39] Gonzalo Navarro. Indexing highly repetitive string collections, part II: Compressed indexes. ACM Comput. Surv., 54(2):26:1–26:32, 2022. doi:10.1145/3432999.
  • [40] Gonzalo Navarro, Giuseppe Romana, and Cristian Urbina. Smallest suffixient sets as a repetitiveness measure. arXiv preprint arXiv:2506.05638, 2025. doi:10.48550/arXiv.2506.05638.
  • [41] Takaaki Nishimoto and Yasuo Tabei. Optimal-time queries on BWT-runs compressed indexes. In Nikhil Bansal, Emanuela Merelli, and James Worrell, editors, 48th International Colloquium on Automata, Languages, and Programming, ICALP 2021, Glasgow, Scotland (Virtual Conference), July 12-16, 2021, volume 198 of LIPIcs, pages 101:1–101:15. Schloss Dagstuhl – Leibniz-Zentrum für Informatik, 2021. doi:10.4230/LIPIcs.ICALP.2021.101.
  • [42] Nicola Prezza. Optimal substring equality queries with applications to sparse text indexing. ACM Trans. Algorithms, 17(1):7:1–7:23, 2021. doi:10.1145/3426870.
  • [43] Simon J. Puglisi and Bella Zhukova. Relative Lempel-Ziv compression of suffix arrays. In Christina Boucher and Sharma V. Thankachan, editors, String Processing and Information Retrieval - 27th International Symposium, SPIRE 2020, Orlando, FL, USA, October 13-15, 2020, Proceedings, volume 12303 of Lecture Notes in Computer Science, pages 89–96. Springer, 2020. doi:10.1007/978-3-030-59212-7_7.
  • [44] Massimiliano Rossi, Marco Oliva, Paola Bonizzoni, Ben Langmead, Travis Gagie, and Christina Boucher. Finding maximal exact matches using the r-index. J. Comput. Biol., 29(2):188–194, 2022. doi:10.1089/cmb.2021.0445.
  • [45] Massimiliano Rossi, Marco Oliva, Ben Langmead, Travis Gagie, and Christina Boucher. MONI: A pangenomic index for finding maximal exact matches. J. Comput. Biol., 29(2):169–187, 2022. doi:10.1089/cmb.2021.0290.
  • [46] Vikram Shivakumar, Omar Y. Ahmed, Sam Kovaka, Mohsen Zakeri, and Ben Langmead. Sigmoni: Classification of nanopore signal with a compressed pangenome index. Bioinform., 40(Supplement_1):i287–i296, 2024. doi:10.1093/bioinformatics/btae213.
  • [47] Esko Ukkonen. On-line construction of suffix trees. Algorithmica, 14(3):249–260, 1995. doi:10.1007/BF01206331.
  • [48] Peter Weiner. Linear pattern matching algorithms. In 14th Annual Symposium on Switching and Automata Theory, Iowa City, Iowa, USA, October 15-17, 1973, pages 1–11. IEEE Computer Society, 1973. doi:10.1109/SWAT.1973.13.
  • [49] Derrick E Wood, Jennifer Lu, and Ben Langmead. Improved metagenomic analysis with Kraken 2. Genome Biology, 20:1–13, 2019.
  • [50] Derrick E Wood and Steven L Salzberg. Kraken: ultrafast metagenomic sequence classification using exact alignments. Genome Biology, 15:1–12, 2014.
  • [51] Mohsen Zakeri, Nathaniel K Brown, Omar Y Ahmed, Travis Gagie, and Ben Langmead. Movi: a fast and cache-efficient full-text pangenome index. iScience, 27(12), 2024.