Relative Compressed Reverse Suffix Array
Abstract
Suffix trees and suffix arrays are two fundamental data structures in the field of string algorithms. For a string (a.k.a. text or sequence) of length over an alphabet of size , these structures typically require bits of space. The FM-index provides a compressed representation of the suffix array in bits, allowing for efficient queries on both the suffix array and its inverse array in near logarithmic time. In certain applications, such as approximate pattern matching (i.e., with wildcards, mismatches, edits), there is a need to access the suffix array of a text, as well as the suffix array of text’s reverse. Motivated by this, we explore the possibility of encoding the suffix array of the reversed text in a compact form, assuming the availability of the FM-index for the original text. Our first solution is an -bit (relative) encoding of the suffix array of the reversed text, with the time for decoding an entry being only times that of decoding an entry in the text’s suffix array using FM-index. We then demonstrate how to reduce the space to bits for a parameter , while multiplicative factor in time becomes approximately . We can also support inverse suffix array and longest common extension queries on the reversed text. These results are achieved through some careful and non-trivial application of various succinct data structure techniques.
Keywords and phrases:
String Matching, Text Indexing, Data Structures, Suffix TreesFunding:
Mano Prakash Parthasarathi: U.S. National Science Foundation (NSF) award CCF-2315822.Copyright and License:
Sharma V. Thankachan; licensed under Creative Commons License CC-BY 4.0
2012 ACM Subject Classification:
Theory of computation Pattern matchingEditors:
Meena Mahajan, Florin Manea, Annabelle McIver, and Nguyễn Kim ThắngSeries and Publisher:
Leibniz International Proceedings in Informatics, Schloss Dagstuhl – Leibniz-Zentrum für Informatik
1 Introduction
The suffix tree data structure [22, 33, 34] has long been a fundamental tool in string processing, enabling tasks such as pattern matching in time linear in the pattern length. However, their use has been limited in practice due to their high memory usage. Suffix arrays [21] were introduced as a more memory-efficient alternative that can perform most of the tasks as suffix trees. Both suffix trees and suffix arrays of a text of length still require bits to store, while the text itself only needs bits, where is the alphabet size. The major breakthrough came in 2000 with the FM-index [7], along with another important development called the compressed suffix array [14]; both of these encode the suffix array in succinct (even compressed) space. Since then, compressed text indexing has continued to be an active area of research, with the FM-index emerging as a foundational component in many bioinformatics tools [18, 20].
In its standard form, the FM-index is essentially the Burrows-Wheeler Transform (BWT) of the text, stored in a data structure that supports rank queries (typically using a wavelet tree [13, 24]), along with a sampled subset of suffix array values. The wavelet tree part uses bits, and supports rank queries in time . For a parameter , the number of sampled suffix array values is and its storage takes bits. To keep this extra space within bits, is typically chosen as . With this, the suffix array (SA) and inverse suffix array (ISA) queries can be supported in time . With additional bits, we can obtain an encoding of the suffix tree itself that supports various queries in time close to [31, 30]. Recent results have revealed the possibility of achieving even more space-efficient encodings of suffix arrays/trees when the data is highly repetitive [10, 16, 26, 27].
We investigate the problem of compactly encoding the suffix array of the reverse of a text, assuming access to the text’s FM-index in its standard form (i.e., the Burrows–Wheeler Transform represented as a wavelet tree together with a sampled suffix array). While this is a natural question in its own right, solutions to it have important applications in text indexing for approximate string matching. A common technique for supporting pattern matching with mismatches or “don’t care” characters involves maintaining both the suffix array or tree of the text and that of its reverse, along with a range query data structure built from specific points derived from these structures [2]. For a comprehensive survey of various results based on this technique, we refer the reader to Lewenstein [19]. See also the solutions for contextual pattern matching [1, 25], bidirectional indexes [17], and affix arrays [32] for further applications. Reducing the memory footprint of the data structures associated with the reversed text can significantly reduce the overall space usage in such applications. We highlight that our problem aligns with the broader theme of relative text indexing, such as relative suffix trees [6] and relative FM-indexes [3], where the goal is to encode a data structure over a dataset by leveraging the availability of the same structure over a closely related dataset. The fact that, in our case, one text is essentially the reverse of the other introduces significant structure to the problem.
This problem was introduced by Ganguly et al. [12], who presented an algorithm to decode the suffix array values of the reversed text directly from the text’s FM-index, without requiring any additional data structures. However, it was heuristic in nature. Specifically, its query time is proportional to the length of the shortest unique substring of the text ending at the value returned, which can be in the worst case. Therefore, our goal is to support suffix array (and inverse suffix array) queries on the reversed text in time close to that of suffix array queries on the original text. We present our results next.
Our Results
Let denote the text to be indexed, where the characters belong to an integer alphabet of size . We can represent the text’s Burrows–Wheeler Transform (BWT) as a (multiary) wavelet tree in bits of space, supporting basic wavelet tree operations (rank, select, access) in time and range quantile queries in time . By maintaining some auxiliary structures of space bits for an integer parameter , we can support suffix array (SA) and inverse suffix array (ISA) queries in time . We obtain the following results.
-
1.
Our first result is that suffix array queries on the reversed text can be supported in time with an auxiliary structure of bits of space.
-
2.
We then generalize the above result by introducing a parameter , achieving a space usage of bits and a query time .
We also show how to support inverse suffix array queries on the reversed text within the same space and in time , which is based on a simple method for answering longest common extension queries on the reversed text. As shown in [31, 30], we can use extra bits to obtain a succinct encoding of the suffix tree of the reversed text that supports various standard operations efficiently.
2 Notation and Preliminary
Throughout this paper, let denotes the text to be indexed and denotes the alphabet set. The -th character of is denoted by and the substring is denoted by , where and denotes concatenation. The string is empty if . We also use for and for . A substring is called a suffix if and a prefix if ; also is a proper prefix if and is a proper suffix if . For any string , we denote its reverse by . Without loss of generality, assume that the characters in our alphabet set corresponds to integers in the range , where . Also, let denote the first character in lexicographic order (equivalently, ) and iff , ensuring that no suffix is a prefix of another suffix.
We call a data structure auxiliary if it is used to support operations assuming some related structures are available; otherwise, it is considered standalone. We assume the standard word RAM model of computation with word size bits.
2.1 Succinct Data Structure Toolkit
2.1.1 Rank/select Queries, Indexible Dictionaries and Wavelet Trees
Let , where . We define three basic operations.
-
is .
-
, where , is the number of ’s in .
-
is the position of -th occurrence of in .
When , we can maintain in bits and support all three operations in time [28]. Another representation, called indexible dictionary takes bits, where is the number of ’s in [29]. It supports the above operations in time. Interestingly, it can support in time, and also when (referred to as partial rank) in time. We will use this result extensively.
For a general alphabet , we have the wavelet tree data structure that uses bits of space and supports all three basic operations in time [13]. It can also support range quantile queries in time [11], where the goal is to find the -th smallest element in , given the tuple . Multiary wavelet trees offer further improvements, reducing the time complexity of the three basic operations to [8]; however, the time for range quantile queries remains . Also note that the term in space can be made for any constant using efficient bit string representations [28]. We refer to Navarro’s survey for further reading on this topic [24]. Moving forward, we use to denote the time complexity of the basic operations, and to represent the time complexity of a range quantile query.
2.1.2 Range Minimum Query (RMQ)
Let be an array of numbers. A range minimum query returns the position , where is the smallest element in . By maintaining a standalone data structure of space bits, we can support RMQ in time [9].
2.1.3 Succinct Representation of Ordinal Trees
The topology of an ordinal tree of nodes can be represented in bits and support the following operations in time [15, 23]. We specify a node by its preorder rank.
-
returns the parent of node .
-
returns the lowest (farthest from the root) common ancestor of nodes and .
-
returns the number of leaves in the subtree of node .
-
returns the number of ancestors of node .
-
returns the ancestor of node at .
-
range of leaves of any given node , where -th (resp., -th) leaf in the tree represents the leftmost (resp., rightmost) leaf in the subtree of .
2.2 Suffix Tree, Suffix Array and Longest Common Prefix (LCP) Array
The suffix of starting at position is . The circular suffix of , starting at position is .
We define the suffix tree of text as a compacted trie of all circular suffixes of . This is equivalent to the standard definition (i.e., without the term “circular”), since iff . It consists of leaves and less than internal nodes. The edges are (implicitly) labeled with substrings of . We use to denote the concatenation of edge labeled on the path from root to node . Also, let be the length of (called string depth). The -th leftmost leaf in the suffix tree is denoted by . The suffix array and the inverse suffix array of are the arrays and , respectively, where and iff the -th smallest circular suffix in lexicographic order is . Equivalently, .
For a string , the locus node (if it exists) is the node closest to root such that is a prefix of and the range of leaves of is called the suffix range of , denoted by . The set denotes the occurrences of in . The longest common extension, denoted by is the length of the longest common prefix of the suffixes of starting positions and , which is the same as , where is the lowest common ancestor (LCA) of leaves and .
The longest common prefix array is an array where . Therefore, is the smallest element in , where and . The permuted longest common prefix array is defined as . Note that the argument of is a leaf position in the suffix tree, whereas that of is a position in the text. We will later see that array can be encoded in bits. See Table 1 for an example.
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | |
| [1..12] | m | i | s | s | i | s | s | i | p | p | i | $ |
| [1..12] | 12 | 11 | 8 | 5 | 2 | 1 | 10 | 9 | 7 | 4 | 6 | 3 |
| [1..12] | 6 | 5 | 12 | 10 | 4 | 11 | 9 | 3 | 8 | 7 | 2 | 1 |
| [1..12] | 0 | 1 | 1 | 4 | 0 | 0 | 1 | 0 | 2 | 1 | 3 | - |
| [1..12] | 0 | 0 | - | 1 | 4 | 3 | 2 | 1 | 0 | 1 | 1 | 0 |
| [1..12] | i | p | s | s | m | $ | p | i | s | s | i | i |
| [1..12] | 12 | 2 | 11 | 5 | 8 | 1 | 9 | 10 | 3 | 6 | 4 | 7 |
| [1..12] | 6 | 2 | 9 | 11 | 4 | 10 | 12 | 5 | 7 | 8 | 3 | 1 |
| [1..12] | 0 | 1 | 1 | 4 | 0 | 0 | 1 | 0 | 2 | 1 | 2 | - |
| [1..12] | 0 | 1 | 2 | 2 | 4 | 1 | - | 0 | 1 | 0 | 1 | 0 |
2.3 Prefix Tree, Prefix Array and Longest Common Suffix (LCS) Array
We now introduce the prefix tree and prefix array of the text, which are equivalent to the suffix tree and suffix array of the reversed text. These alternative definitions are introduced purely for notational convenience.
The prefix of ending at position is . The circular prefix of ending at is and its reverse is . The prefix tree of is a compacted trie of the reverse of all circular prefixes of . It will have leaves and less than internal nodes, and the edges will be labeled as in the suffix tree, but with substrings of . We shall reuse the notations , and as before when the context is clear. We define prefix array and inverse prefix array of as and iff is the “reverse” of the circular prefix of ending at . Define as the length of the longest common suffix of the prefixes of ending at positions and . Therefore, , where is the LCA of leaves and in the prefix tree. The longest common suffix (LCS) array is an array where and the permuted longest common suffix (pLCS) array is such that . See Table 1 for an example.
2.4 The FM-index
The FM-index [7] is a compressed representation of the suffix array , based on the text’s BWT [5]. It is a self-index, meaning it does not require access to the original text in order to function. The BWT of , denoted by is a permutation of characters in , where denotes the last character of -th lexicographically smallest circular suffix of . In other words, if and is otherwise. See Table 1 for an example.
The Last-to-Front operation is defined as if and is otherwise. Moreover, , where and . By maintaining as a wavelet tree, along with for all , in bits, we can support operation in time.
We next focus on and operations. Let if and is if , then . For a parameter , explicitly store the pairs with being a multiple of ; space is bits. To decode , where is not stored, we compute until we find an , where is stored, and return . To decode , where is not stored, we find and (note that is stored) and return , where . In both cases, the sampling scheme guarantees and the resulting time complexity, denoted by , is .
We can also extract any substring in time as follows: find , successively and output the string .
Lemma 1.
Suppose the text’s is available as a wavelet tree supporting basic operations (i.e., and ) in time, then with extra bits, we can support queries in time and extract any substring in time . Here, is a parameter.
2.5 Longest Common Extension (LCE) and Related Queries
The following two results, along with the succinct representation of the suffix tree topology as in Section 2.1.3, gives the compressed representation of the suffix tree. We present sketches of the proofs for these known results, since we will be adapting them in subsequent sections.
Lemma 2 (Sadakane [31]).
The array can be encoded in bits, such that for any position in the text can be retrieved in time.
Proof.
Key observation is that for all . To prove this, note that it is trivially true when . Otherwise, let . Then , therefore is atleast . By rearranging the inequality and by adding on both sides, we get . This means, the function is non-decreasing. Moreover , because and hence . Therefore, we can store the function as a bit string with time rank/select support in bits. To decode , we first find , the position of -th in in time. Then we have , the number of ’s until , and .
Lemma 3 ( Queries).
By maintaining an auxiliary structure of space bits along with the FM-index, we can answer queries in time.
Proof.
Maintain the encoding of the array described in Lemma 2 and an RMQ data structure over the array, but without explicitly storing the array itself. To compute , find and . Without loss of generality, assume that . Then find , where is the smallest in using an RMQ in time. Then compute and return . Total time is .
We next present an additional result that will be used later.
Lemma 4 ( Queries).
Let be an integer parameter. By maintaining an auxiliary structure of space bits, we can compute for any given via number of queries.
Proof.
For any given text of length , there exists a standalone data structure of space words, equivalently bits, that in constant time either correctly computes or determines that for any given [4]. We maintain this data structure over the reversed text, which allows us to correctly compute or to determine that . When , we exploit the following observation: if and only if , and binary search on . This will give us in number of queries.
3 Relative Encoding of in Extra bits
The prefix tree/array of corresponds to the suffix tree/array of . Specifically, the -th entry in the suffix array of is . Therefore, it suffices to design an encoding of the prefix array.
3.1 Basic Components
Let be an integer parameter (positive or negative). We now introduce arrays and , which are generalizations of array and array as follows:
The encoding technique by Sadakane (see Lemma 2) extends to the array as follows.
Lemma 5.
Let be an integer parameter (positive or negative). We can encode in bits, and return for any text position in time.
Proof.
We first prove that for all . Clearly, the inequality holds when . Otherwise, let and . Then we can see that if is positive and if is negative. In both cases, . By rearranging the inequality as in the proof of Lemma 2, we obtain a non-decreasing function . We store as bit string with time rank/select support in bits. Then is given by .
Lemma 6 (Sampled ).
Let be an integer parameter (positive or negative) and be a set of size . There exists a standalone structure of space bits that returns for any given in time.
Proof.
We modify the proof in Lemma 5 as follows. Define a bit string , where iff . Define another bit string , where . Maintain and as indexible dictionaries in bits with efficient rank/select support. Given any , we find in time using a partial-rank query. Then find and report .
The Longest common suffix (LCS) array and the permuted longest common suffix (pLCS) array can also be generalized as follows.
Since and are equivalent to and of the reverse of , the following result is an immediate corollary of Lemma 6.
Corollary 7 (Sampled ).
Let be an integer parameter (positive or negative) and be a set of size . There exists a standalone structure of space bits that returns for any given in time.
3.2 The Data Structure
Assuming the availability of an FM-index of in its standard from as described in Section 2.4, we now present components in the relative encoding of the prefix array of . For , define as round to the integer which is the next power of . i.e., . Here if and is if , and is the smallest where . Therefore, . Also let . We denote the predecessor and successor of that are multiples of by and , respectively. Therefore, when divides , we have .
3.2.1 Technical Overview
If is divisible by , we explicitly store using bits. If is divisible by , but not by , we encode relative to either or (depending on the case, to be described) using bits. Similarly, if is divisible by , but not by , we encode relative to either or using bits. More generally, we encode relative to either or using bits, where is the smallest integer such that is divisible by . The function is chosen carefully such that the total space usage is bounded by a sum that converges to bits. The algorithm for decoding works as follows: for , decode either or (depending on the case) and terminate at where , thereby yielding . We present the details next.
3.2.2 Components of the Data Structure
For each , maintain arrays as described below.
-
If is divisible by , we store explicitly in as .
-
If is not divisible by , we find the smallest integer where is divisible by ; such an exists since . Then store a value in as . The value is determined by certain nodes in the prefix tree, which in turn are based on and as illustrated in Figure 1. Let and , and be the lowest node among and . Also let and node be the child of on the path to and be the leading character on the edge from to . This means that a substring of matching ends at position , and therefore starts at . Consequently, must contain the entry . Then is defined as the offset within the suffix range of , Specifically,
Finally, ; therefore, we can store using bits.
While decoding , the answer is readily available from if is a multiple of . Otherwise, we utilize the relationship , where is retrieved from ; however, and are not explicitly stored. To find them, we maintain the following auxiliary structures.
-
The succinct encodings of the topologies of both the suffix tree and the prefix tree.
-
For each , we maintain a collection of structures as in Corollary 7. Precisely, for a fixed , we assign and make a separate structure for each non-zero value of . Note that for a fixed , and the number of structures is .
This completes the description of our data structure.
3.2.3 Space Complexity Analysis
The length of is and each entry in is encoded in bits. Therefore, space is bits for a fixed and bits for all combined. The tree topologies takes bits. The space (in bits) required by all versions of the structures in Corollary 7 can also be bounded by , as shown below, resulting in an overall space complexity of bits.
3.3 Algorithm for Decoding
At first, compute , the smallest integer such that divides . Then, identify nodes and in the prefix tree, and let be the lowest node among them. This step takes only time using tree encodings. Let and be the leading character on the edge from to its child on the path to . Our next goal is to compute and the suffix range of , then return . There are two cases.
-
1.
Case (i.e., or ): In this case, is encoded relative to . We start with an assumption that has already been computed. Observe that , where . Note also that and . Recall that we already maintain the data structure of Corollary 7 for this specific choice of and ; querying it yields , and thus , in time. We then infer and invoke the steps below.
-
(a)
Find the suffix range of : Find the leaf in the suffix tree, where (this leaf corresponds to the suffix ), then find its ancestor such that , and return the range of leaves of as the answer. Note that exists and it can be computed via binary search, specifically number of queries. The first step requires an query (in time ), the second step takes time and the third step takes time.
-
(b)
Find : Let be the range of leaves of (in the prefix tree) and let . Then, will be the -th leftmost leaf in the subtree of , which implies will be the -th smallest character in . So, perform a range quantile query in time and find .
-
(c)
Find the suffix range of : Let (resp., ) be the first (resp., last) occurrence of in . Then, will be the suffix range of which can be answered in time.
-
(d)
Compute and return it. Note that is stored explicitly, and hence this step takes time.
Total time is .
-
(a)
-
2.
Case (i.e, ): In this case, is encoded relative to . As before, we assume that has already been computed. Observe that , where . Note also that and . Recall that we already maintain the structure of Corollary 7 for this specific choice of and ; querying it yields in time. We then infer , invoke the same steps as before and obtain in time.
In summary, decoding reduces to decoding either or (depending on the case) in time, which recursively reduces to decoding or , and so forth, until reaching or , which are explicitly stored. The overall time is .
Theorem 8.
Let the Burrows-Wheeler Transform (BWT) of a text be maintained in a data structure that supports basic queries (, , and ) in time, and range quantile queries in time. Then, for any parameter , we can maintain a sampled subset of suffix array values using bits of additional space, and support suffix array (SA), inverse suffix array (ISA), and longest common extension (LCE) queries in time .
By maintaining an auxiliary structure of space bits, we can support prefix array (PA) queries in time .
By employing the multiary wavelet tree, where and [8], and setting , we obtain the following result.
Corollary 9.
For any text over an alphabet of size , we can represent its Burrows–Wheeler Transform using a (multiary) wavelet tree in bits of space, supporting basic wavelet tree operations (rank, select, access) in time and range quantile queries in time . By maintaining some auxiliary structures of space bits, we can support suffix array (SA), inverse suffix array (ISA), and longest common extension (LCE) queries in time , and prefix array (PA) queries in time .
4 Relative Encoding of in Sublinear Space
In this section, we present an -bit (relative) encoding of , where is an integer parameter. Without loss of generality, we assume that is a power of .
4.1 Basic Components
We now present several useful results.
Lemma 10 (Approximate in small space).
Let be an integer parameter (positive or negative). There exists a standalone structure of space bits that returns in time, where .
Proof.
We obtain this result by modifying Lemma 6. The idea is to select a set of sampled positions and store values of only those . The set is constructed as follows. Initially . Then for to , we include in iff is a multiple of or , where is the largest value in currently. The size of is since and is non-decreasing. For a query , we return as , where is the predecessor of in . The correctness follows from that fact that and , which implies .
We now present the implementation details. Define a bit string corresponding to , where iff . Define another bit string , where . We maintain both and as indexible dictionaries with efficient rank/select support. The space required is bits since both and are of size with number of ’s. To recover an approximate value of , we first find and using a partial rank query in time. Then , the predecessor of in is for the , where , which can be computed in time via binary search. Finally, get and return .
Lemma 11 (Approximate in small space).
Let be an integer parameter (positive or negative). There exists a standalone structure of space bits that returns in time, where .
Proof.
Follows from Lemma 10, because is equivalent to of text’s reverse.
Lemma 12 (Exact in small space).
By maintaining an -bit auxiliary structure with the FM-index, we can return for any in time.
Proof.
Maintain the structure in Lemma 10 for . Let , then . Find first. Now we know and . Therefore, simply extract the substrings and and compute naively.
Lemma 13 (Exact in small space).
By maintaining an -bit auxiliary structure with FM-index, we can return in time time.
Proof.
We divide the array into blocks of size . i.e., , etc. Also let be the smallest element in -th block. Maintain a range minimum query structure over array (space required is bits). Besides this, we will use the result in Lemma 12. When a query comes, we compute as follows. Let and . Without loss of generality, lets assume that . To efficiently find our answer , we invoke the following procedure.
-
If , we extract and return the minimum.
-
Otherwise, we extract , where and return the minimum.
In both cases, we are required to make two queries, number of queries, followed by number of queries, which makes the total time .
4.2 The Data Structure
4.2.1 Technical Overview
We categorize a query as Type-A if is divisible by (recall that is a power of ), and as Type-B otherwise. These two types are handled separately. For Type-A queries, we modify our -bit solution in a relatively simple manner. Instead of maintaining structures up to levels, we stop at an earlier stage, which suffices to handle such queries and also helps bound the space. Furthermore, we substitute the standard suffix and prefix tree topologies with their sampled counterparts. However, for Type-B queries, we first decode the values of the predecessor and the successor which are multiples of (i.e., and ), by treating them as Type-A queries. Then, we decode all the entries in , first in an unsorted manner; afterward, we sort them to obtain . We accomplish this by splitting this range into the minimal number of subranges such that each subrange corresponds to a subtree of the prefix tree, and processing each subrange carefully. This part is more technical.
4.2.2 Handling Type-A Queries
Observe that our -bit encoding of composed of two tree topologies and several components corresponding to each . However, only the components corresponding to are utilized when decoding , where is the smallest integer in such that divides (recall that is round to the next power of ). We exploit this fact to design a space efficient structure for Type-A queries. Let be the integer, where . We now maintain the components in Section 3.2.2 for only selected values of (with some modifications) as follows:
-
1.
All values of ;
-
2.
, but modify the value of to .
-
3.
, but modify the value of to .
The resulting space in bits is
Our previous algorithm (as described in Section 3.3) can be applied to determine with the same time complexity. However, the topologies of suffix tree and prefix tree still takes bits. We replace them with the topologies of the sparse prefix tree (SPT) and sparse suffix tree (SST), which require less space. Additionally, we maintain the small space structure in Lemma 13 supporting queries.
Replacing Prefix Tree with Sparse Prefix Tree (SPT)
We sample a subset of nodes in the prefix tree as follows:
-
1.
leaves , where is a multiple of ;
-
2.
the lowest common ancestor (LCA) of every pair of consecutive leaves sampled in step 1;
-
3.
the leftmost and rightmost descendant leaves of sampled nodes obtained in step 2.
Let be the set of sampled leaves obtained after the above procedure. Then, the SPT is the compacted trie built from the reverse of circular prefixes corresponding only to the leaves in – that is, a sparse prefix tree. We maintain its topology in succinct space and a bit string , where iff , as an indexible dictionary. The space required is bits as there are 1’s in . We now present some useful results.
Lemma 14.
Given two sampled leaves in the prefix tree, the size of their can be returned in time using SPT and the associated bit string.
Proof.
The sampled leaf (resp., ) in the prefix tree corresponds to the leaf (resp., ) in SPT. Therefore, find the range of leaves in the subtree of the node in SPT and return .
The prefix tree topology play the following role in our earlier algorithm. Given , (i) find which among the nodes and is lower (call it ) to decide which case to use in the decoding procedure and (ii) return the range of leaves of (note that we don’t require the pre-order rank of ). Since are all divisible by (hence sampled) in the case of Type-A queries, we can apply Lemma 14 and find the range of leaves of and first, then infer iff the range of is the same or contained within the range of . The subsequent steps in the recurrence also work since both and are divisible by for all . In summary, a sparse prefix tree topology can perform the required functionalities in our algorithm without any performance slowdown.
Replacing Suffix Tree with Sparse Suffix Tree (SST)
The SST is the compacted trie constructed from the circular suffixes corresponding to the leaves of the suffix tree, where is a multiple of . We maintain its topology in succinct space, requiring bits.
The suffix tree topology serves the purpose of finding the suffix range of in time, given (i) the length of (this can be computed using as in Section 3.3), (ii) a leaf in the suffix tree, where is a prefix of , (iii) the size of the suffix range of , i.e., (specifically, is given, where is a node in the prefix tree). It is worth noting that this task can be accomplished without the suffix tree topology, and even without the third input parameter. We can exploit the fact that if and only if , and hence we can apply binary search on and determine the answer using queries.
We speed up this process by using the additional information in (iii) as follows. If , we still apply the binary search. The number of queries required is . Otherwise, find an approximate range using SST first, and then apply binary search on ranges of size as follows.
-
1.
Find a value closer to , such that is a multiple of (thus is sampled) and is also prefixed by as follows. Let and . We fix if , otherwise (in this case is guaranteed as ).
-
2.
Find -th leaf in SST, and return the range of leaves of its lowest ancestor with . This step takes only time (via queries as before, but on SST). Observe that our sampling scheme guarantees and . Therefore we can now restrict our binary search into a smaller range of size , requiring only and queries.
This subroutine for finding suffix range of takes time. After that, we continue with steps (b), (c), and (d) as in Section 3.3.
By substituting the space–time complexities of the components, incorporating updated data structures, we obtain the following bound for Type-A queries.
Lemma 15 (Type-A Queries).
By maintaining auxiliary structures of space bits in total, we can answer Type-A queries in time
4.2.3 Handling Type-B Queries
Type-B queries require a more involved solution than Type-A queries. Maintain the structure in Lemma 11 supporting queries, for values of in . Also associate bits of satellite information (to be defined shortly) with each integer in that is a multiple of . The total space is bits.
To retrieve , where is not divisible by , we employ a procedure that decodes a segment of containing . Let , , and . We now proceed to define some nodes in the prefix tree as illustrated in Figure 2.
-
are nodes that lie on the path from to (excluding endpoints), ordered in descending , such that and for is the lowest ancestor of whose child on the path to has a right sibling. Let denote the range of leaves of for . Therefore, denotes the range of leaves after , such that the of any of those leaves with is a node in . The following observation allows us to jump from node to node for all .
Observation 16.
For all we have ; therefore .
-
are nodes that lie on the path from to (excluding endpoints), ordered by descending , such that and for is the lowest ancestor of whose child on the path to has a left sibling. Let denote the range of leaves of for . Therefore, denotes the range of leaves before , such that the of any of those leaves with belongs to . The following observation allows us to jump from node to node for all .
Observation 17.
For all , we have ; therefore .
Our procedure for decoding depends on which of the intervals , or contains . The satellite information associated with is (all four values are bounded by ), which helps to decide the case.
CASE
First obtain using a Type-A query, then initialize and , the length of the prefix ending at . Then decode in steps; at step , we compute and . Note that . Let be the prefix of of length and be the -th character of . Therefore, and . When , we let and .
-
1.
Finding : Observe that is the largest such that contains a character . However, finding can be expensive. Thankfully, we have an alternative procedure to verify this condition for a given . Find , which is an entry in , then find the largest number before , and the smallest number after , such that , using wavelet tree queries. The condition is satisfied if and only if or . We next determine an such that , meaning we only need to iterate over the values of in for finding . To find , we rely on observation 16 that and . Therefore, , and we compute in time (see Lemma 11), and set . The total time is .
-
2.
Finding : At first, we find an approximation using SPT and the associated bit vector as follows. Note that and the leaf is sampled (recall SPT’s construction). Therefore, if is also sampled (i.e., , then we can find the exact value of in time using Lemma 14. Otherwise, find the leaves in SPT, the child of their LCA on the path to , and the range of leaves of that child. Then return as . Our sampling scheme guarantees that the value returned lies in the range . The time complexity is . We now proceed to computing the exact value of . Since , we have . Therefore we compute the range as follows. To begin with, we know an entry , as well as . At the point, we can follow the same procedure detailed in Section 4.2.2, where we first identify an approximate range that is sufficiently close to the actual one using sparse suffix tree in time, then perform a binary search requiring only LCE and ISA queries. The time required is .
-
3.
Finding : Let be the leading character on the path from to its child on the path to . Count the entries in that are above (using a wavelet tree query). This gives the number of leaves in the range . Therefore we simply add with this count and return as . Time required is .
-
4.
Finding : The set is a collection of elements in , which can be obtained in time per element using wavelet tree and queries. However, we do not know the order in which they appear in ; therefore our next goal is to recover by sorting the elements in in the ascending order of their values. We first present a simple solution, and then describe a slightly improved one.
-
(a)
A simple solution using queries: By fixing , we maintain the structure in Lemma 4 without changing the asymptotic space complexity, which supports queries in time. Then, for any , we can decide the relative order of and by comparing the characters and . Therefore, an efficient comparison-based sorting algorithm (such as merge sort) can be used to sort the elements of in ascending order of their values using number of queries. The resulting time complexity for this step is
-
(b)
An alternative solution: Our goal here is to avoid the direct use of queries, and thereby removing the term in the previous time complexity. To achieve this, we reconstruct the subtree rooted at on the fly. For any node in the subtree rooted at , let denotes the set of values corresponding to the leaves in the subtree of . Iterating over , our algorithm return the sets , in that order, where nodes are the children (in the left to right order) of node . Note that the preorder rank of is not known even after processing . Therefore, based on , we assign to a unique label, defined as the ordered pair consisting of the size of and the smallest element of . With this labeling and parent–child information for all internal nodes, we can easily reconstruct the tree in a top-down fashion and recover . We now present the details of processing a specific . The first step is to compute , which is given by the expression below when (in that case ); when , it will not return any value.
Instead of evaluating this expression by applying directly, we compute in time (see Lemma 11), where . Then, iterate over , compute , and consider the following two cases:
-
i.
If , then we know . Therefore discard .
-
ii.
Otherwise we have . In that case, extract the substrings and and compare them. If the substrings differ, we can compute (thus compute ) and determine their lexicographic order (and thus the lexicographic order of and ). If the substrings match, we infer that , and therefore both and lie in the subtree of the same child of , and comes before in lexicographically.
The above step for a specific takes time. By taking the maximum value of over all that satisfy the required condition on the lexicographic order, we obtain . We next collect all positions such that , group them into sets according to the character , and output these sets in order of increasing character value they correspond to. It is straightforward to verify that the sets produced in this manner are exactly . Moreover, every internal node in the subtree rooted at will be processed after we have iterated over all . The overall time complexity of this step is .
-
i.
We use the second method, although its time complexity is quadratic in the size of the tree, because the first method would add extra factors to the time complexity.
-
(a)
The combined time for all 4 steps for all , where is bounded as follows:
By substituting and , the expression simplifies to
CASE
Let and be the leading character on the path from to its child on the path to and be the leading character on the path from to its child on the path to . Then the set is the collection of elements in . Since , are readily available (via Type-A query), the elements in the set can be easily extracted in time per element, but not in the order as they appear in . Finally, to recover , we follow the same procedure as in the first case. The resulting time is .
CASE
Here we obtain first using a Type-A query, then initialize and , the length of the prefix ending at . Then decode in steps, where at step , we compute , , and . Note that . Suppose and , then the set elements in is given by . This is analogous to that of the first case, therefore we invoke a symmetric procedure to handle this case. In contrast to the first case, where we rely on Observation 16 and use queries, here we rely on Observation 17 and use queries. Total time is time (similar to the first case).
Lemma 18 (Type-B Queries).
The combined space of all auxiliary structures for Type-B queries is bits and the query time is .
Theorem 19.
Let the Burrows-Wheeler Transform (BWT) of a text be maintained in a data structure that supports basic queries (, , and ) in time, and range quantile queries in time. Then, for any parameter , we can maintain a sampled subset of suffix array values using bits of additional space, and support suffix array (SA) and inverse suffix array (ISA) queries in time . By maintaining an auxiliary structure of space bits for a parameter , we can support prefix array (PA) queries in time
Additionally we can support queries in time and queries in time .
By employing the multiary wavelet tree, where , and setting and , we obtain the following result.
Corollary 20.
Let be a text over an alphabet of size . We can maintain its Burrows-Wheeler Transform (BWT) as a wavelet tree data structure in bits that supports basic queries (rank, select, access) in time and range quantile queries in time . For an integer parameter , we can maintain an auxiliary structure of space bits and support suffix array (SA) and inverse suffix array (ISA) queries in time , and prefix array (PA) queries in time .
Additionally we can support queries in time and queries in time .
5 A Note On Inverse Prefix Array (IPA) Queries
We present a simple approach for supporting queries. Assuming the availability of data structures supporting and queries, we maintain the auxiliary structure from Lemma 4 with the parameter set to . This structure requires additional bits of space and supports queries in time .
Given a text position , we compute by performing a binary search over . For a candidate index , we first compute . If , we return and terminate the search. Otherwise, we compute and compare the characters and (which must be different). If , then we conclude that ; otherwise, . This provides the necessary comparison predicate for binary search. The time complexity is .
Theorem 21.
With the structure described in Theorem 19, we can maintain an auxiliary data structure of space bits that supports inverse prefix array (IPA) queries in time .
6 Conclusions
We present a solution for encoding the suffix array and inverse suffix array of the reversed text, assuming the availability of the FM-index of the original text. We can answer suffix array queries on the reversed text in time close to that of suffix array queries on the original text. However, for inverse suffix array queries on the reversed text, we require roughly a factor of more time than for inverse suffix array queries on the original text. Narrowing this gap is an interesting problem, which we leave open for future research.
References
- [1] Paniz Abedin, Oliver A. Chubet, Daniel Gibney, and Sharma V. Thankachan. Contextual pattern matching in less space. In Data Compression Conference, DCC 2023, Snowbird, UT, USA, March 21-24, 2023, pages 160–167. IEEE, 2023. doi:10.1109/DCC55655.2023.00024.
- [2] Amihood Amir, Dmitry Keselman, Gad M. Landau, Moshe Lewenstein, Noa Lewenstein, and Michael Rodeh. Text indexing and dictionary matching with one error. J. Algorithms, 37(2):309–325, 2000. doi:10.1006/JAGM.2000.1104.
- [3] Djamal Belazzougui, Travis Gagie, Simon Gog, Giovanni Manzini, and Jouni Sirén. Relative fm-indexes. In String Processing and Information Retrieval: 21st International Symposium, SPIRE 2014, Ouro Preto, Brazil, October 20-22, 2014. Proceedings 21, pages 52–64. Springer, 2014. doi:10.1007/978-3-319-11918-2_6.
- [4] Philip Bille, Inge Li Gørtz, Mathias Bæk Tejs Knudsen, Moshe Lewenstein, and Hjalte Wedel Vildhøj. Longest common extensions in sublinear space. In Ferdinando Cicalese, Ely Porat, and Ugo Vaccaro, editors, Combinatorial Pattern Matching - 26th Annual Symposium, CPM 2015, Ischia Island, Italy, June 29 - July 1, 2015, Proceedings, volume 9133 of Lecture Notes in Computer Science, pages 65–76. Springer, 2015. doi:10.1007/978-3-319-19929-0_6.
- [5] Michael Burrows. A block-sorting lossless data compression algorithm. SRS Research Report, 124, 1994.
- [6] Andrea Farruggia, Travis Gagie, Gonzalo Navarro, Simon J Puglisi, and Jouni Sirén. Relative suffix trees. The Computer Journal, 61(5):773–788, 2018. doi:10.1093/COMJNL/BXX108.
- [7] Paolo Ferragina and Giovanni Manzini. Opportunistic data structures with applications. In Proceedings of the 41st Annual Symposium on Foundations of Computer Science, pages 390–398. IEEE, 2000. doi:10.1109/SFCS.2000.892127.
- [8] Paolo Ferragina, Giovanni Manzini, Veli Mäkinen, and Gonzalo Navarro. Compressed representations of sequences and full-text indexes. ACM Trans. Algorithms, 3(2):20, 2007. doi:10.1145/1240233.1240243.
- [9] Johannes Fischer and Volker Heun. Space-efficient preprocessing schemes for range minimum queries on static arrays. SIAM J. Comput., 40(2):465–492, 2011. doi:10.1137/090779759.
- [10] 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.
- [11] Travis Gagie, Simon J. Puglisi, and Andrew Turpin. Range quantile queries: Another virtue of wavelet trees. In String Processing and Information Retrieval (SPIRE), volume 5721 of Lecture Notes in Computer Science, pages 1–6. Springer, Berlin, Heidelberg, 2009. arXiv:0903.4726. doi:10.1007/978-3-642-03784-9_1.
- [12] Arnab Ganguly, Daniel Gibney, Sahar Hooshmand, M. Oguzhan Külekci, and Sharma V. Thankachan. Fm-index reveals the reverse suffix array. In Inge Li Gørtz and Oren Weimann, editors, 31st Annual Symposium on Combinatorial Pattern Matching, CPM 2020, Copenhagen, Denmark, June 17-19, 2020, volume 161 of LIPIcs, pages 13:1–13:14. Schloss Dagstuhl – Leibniz-Zentrum für Informatik, 2020. doi:10.4230/LIPIcs.CPM.2020.13.
- [13] Roberto Grossi, Ankur Gupta, and Jeffrey Scott Vitter. High-order entropy-compressed text indexes. In Proceedings of the 14th Annual ACM-SIAM Symposium on Discrete Algorithms, pages 841–850. SIAM, 2003. URL: http://dl.acm.org/citation.cfm?id=644108.644250.
- [14] Roberto Grossi and Jeffrey Scott Vitter. Compressed suffix arrays and suffix trees with applications to text indexing and string matching. SIAM J. Comput., 35(2):378–407, 2005. doi:10.1137/S0097539702402354.
- [15] Jesper Jansson, Kunihiko Sadakane, and Wing-Kin Sung. Ultra-succinct representation of ordered trees with applications. J. Comput. Syst. Sci., 78(2):619–631, 2012. doi:10.1016/J.JCSS.2011.09.002.
- [16] 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.
- [17] Tak Wah Lam, Ruiqiang Li, Alan Tam, Simon C. K. Wong, Edward Wu, and Siu-Ming Yiu. High throughput short read alignment via bi-directional BWT. In 2009 IEEE International Conference on Bioinformatics and Biomedicine, BIBM 2009, Washington, DC, USA, November 1-4, 2009, Proceedings, pages 31–36. IEEE Computer Society, 2009. doi:10.1109/BIBM.2009.42.
- [18] Ben Langmead, Cole Trapnell, Mihai Pop, and Steven L. Salzberg. Ultrafast and memory-efficient alignment of short dna sequences to the human genome. Genome Biology, 10(3):R25, 2009.
- [19] Moshe Lewenstein. Orthogonal range searching for text indexing. In Andrej Brodnik, Alejandro López-Ortiz, Venkatesh Raman, and Alfredo Viola, editors, Space-Efficient Data Structures, Streams, and Algorithms - Papers in Honor of J. Ian Munro on the Occasion of His 66th Birthday, volume 8066 of Lecture Notes in Computer Science, pages 267–302. Springer, 2013. doi:10.1007/978-3-642-40273-9_18.
- [20] Heng Li and Richard Durbin. Fast and accurate short read alignment with burrows-wheeler transform. Bioinformatics, 25(14):1754–1760, 2009. doi:10.1093/BIOINFORMATICS/BTP324.
- [21] Udi Manber and Gene Myers. Suffix arrays: A new method for on-line string searches. SIAM Journal on Computing, 22(5):935–948, 1993. doi:10.1137/0222058.
- [22] Edward M. McCreight. A space-economical suffix tree construction algorithm. Journal of the ACM, 23(2):262–272, 1976. doi:10.1145/321941.321946.
- [23] J. Ian Munro and Venkatesh Raman. Succinct representation of balanced parentheses and static trees. SIAM J. Comput., 31(3):762–776, 2001. doi:10.1137/S0097539799364092.
- [24] Gonzalo Navarro. Wavelet trees for all. J. Discrete Algorithms, 25:2–20, 2014. doi:10.1016/J.JDA.2013.07.004.
- [25] Gonzalo Navarro. Contextual pattern matching. In International Symposium on String Processing and Information Retrieval, pages 3–10. Springer, 2020. doi:10.1007/978-3-030-59212-7_1.
- [26] 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.
- [27] 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.
- [28] Mihai Pătraşcu. Succincter. In 49th Annual IEEE Symposium on Foundations of Computer Science, FOCS 2008, October 25-28, 2008, Philadelphia, PA, USA, pages 305–313. IEEE Computer Society, 2008. doi:10.1109/FOCS.2008.83.
- [29] Rajeev Raman, Venkatesh Raman, and Srinivasa Rao Satti. Succinct indexable dictionaries with applications to encoding k-ary trees, prefix sums and multisets. ACM Trans. Algorithms, 3(4):43, 2007. doi:10.1145/1290672.1290680.
- [30] Luís MS Russo, Gonzalo Navarro, and Arlindo L Oliveira. Fully-compressed suffix trees. In LATIN 2008: Theoretical Informatics: 8th Latin American Symposium, Búzios, Brazil, April 7-11, 2008. Proceedings 8, pages 362–373. Springer, 2008. doi:10.1007/978-3-540-78773-0_32.
- [31] Kunihiko Sadakane. Compressed suffix trees with full functionality. Theory Comput. Syst., 41(4):589–607, 2007. doi:10.1007/S00224-006-1198-X.
- [32] Dirk Strothmann. The affix array data structure and its applications to RNA secondary structure analysis. Theor. Comput. Sci., 389(1-2):278–294, 2007. doi:10.1016/J.TCS.2007.09.029.
- [33] Esko Ukkonen. On-line construction of suffix trees. Algorithmica, 14(3):249–260, 1995. doi:10.1007/BF01206331.
- [34] Peter Weiner. Linear pattern matching algorithms. 14th Annual Symposium on Switching and Automata Theory, pages 1–11, 1973. doi:10.1109/SWAT.1973.13.
