<?xml version="1.0" encoding="UTF-8"?>
<TEI xml:space="preserve" xmlns="http://www.tei-c.org/ns/1.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.tei-c.org/ns/1.0 https://raw.githubusercontent.com/kermitt2/grobid/master/grobid-home/schemas/xsd/Grobid.xsd"
 xmlns:xlink="http://www.w3.org/1999/xlink">
	<teiHeader xml:lang="en">
		<fileDesc>
			<titleStmt>
				<title level="a" type="main">Position Heaps for Permuted Pattern Matching on Multi-Track Strings</title>
			</titleStmt>
			<publicationStmt>
				<publisher/>
				<availability status="unknown"><licence/></availability>
			</publicationStmt>
			<sourceDesc>
				<biblStruct>
					<analytic>
						<author>
							<persName><forename type="first">Takashi</forename><surname>Katsura</surname></persName>
							<email>katsura@shino.</email>
							<affiliation key="aff0">
								<orgName type="department">Graduate School of Information Sciences</orgName>
								<orgName type="institution">Tohoku University</orgName>
								<address>
									<country key="JP">Japan</country>
								</address>
							</affiliation>
						</author>
						<author>
							<persName><forename type="first">Yuhei</forename><surname>Otomo</surname></persName>
							<email>otomo@shino.</email>
							<affiliation key="aff0">
								<orgName type="department">Graduate School of Information Sciences</orgName>
								<orgName type="institution">Tohoku University</orgName>
								<address>
									<country key="JP">Japan</country>
								</address>
							</affiliation>
						</author>
						<author>
							<persName><forename type="first">Kazuyuki</forename><surname>Narisawa</surname></persName>
							<email>narisawa@</email>
							<affiliation key="aff0">
								<orgName type="department">Graduate School of Information Sciences</orgName>
								<orgName type="institution">Tohoku University</orgName>
								<address>
									<country key="JP">Japan</country>
								</address>
							</affiliation>
						</author>
						<author>
							<persName><forename type="first">Ayumi</forename><surname>Shinohara</surname></persName>
							<affiliation key="aff0">
								<orgName type="department">Graduate School of Information Sciences</orgName>
								<orgName type="institution">Tohoku University</orgName>
								<address>
									<country key="JP">Japan</country>
								</address>
							</affiliation>
						</author>
						<title level="a" type="main">Position Heaps for Permuted Pattern Matching on Multi-Track Strings</title>
					</analytic>
					<monogr>
						<imprint>
							<date/>
						</imprint>
					</monogr>
					<idno type="MD5">CD86CE1DE750B14D8FF5C5BC3D279A11</idno>
				</biblStruct>
			</sourceDesc>
		</fileDesc>
		<encodingDesc>
			<appInfo>
				<application version="0.7.2" ident="GROBID" when="2023-03-24T21:29+0000">
					<desc>GROBID - A machine learning software for extracting information from scholarly documents</desc>
					<ref target="https://github.com/kermitt2/grobid"/>
				</application>
			</appInfo>
		</encodingDesc>
		<profileDesc>
			<textClass>
				<keywords>
					<term>string matching</term>
					<term>multi-track</term>
					<term>indexing structure</term>
				</keywords>
			</textClass>
			<abstract>
<div xmlns="http://www.tei-c.org/ns/1.0"><p>A multi-set of N strings of length n is called a multi-track string. The permuted pattern matching is the problem that given two multi-track strings T = {t1, . . . , tN } of length n and P = {p1, . . . , pN } of length m, outputs all positions i such that {p1, . . . , pN</p><p>We propose two new indexing structures for multi-track stings. One is a time-efficient structure for T that needs O(nN ) space and enables us to solve the problem in O(m 2 N + occ) time, where occ is the number of occurrences of the pattern P in the text T. The other is memory-efficient, it requires only O(n) space, whereas the matching consumes O(m 2 N 2 + occ) time. We show that both of them can be constructed in O(nN ) time.</p></div>
			</abstract>
		</profileDesc>
	</teiHeader>
	<text xml:lang="en">
		<body>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="1">Introduction</head><p>The string indexing problem is fundamental and important for information retrieval, and to build an index for a given length n text string that allows us to find all occurrences of a given length m pattern string in the text efficiently. The classical indexing structures, suffix trees <ref type="bibr" target="#b15">[16]</ref> and suffix arrays <ref type="bibr" target="#b10">[11]</ref>, require O(n) space and can be built in O(n) time on a constant-size alphabet <ref type="bibr" target="#b5">[6,</ref><ref type="bibr" target="#b6">7,</ref><ref type="bibr" target="#b8">9,</ref><ref type="bibr" target="#b11">12,</ref><ref type="bibr" target="#b12">13,</ref><ref type="bibr" target="#b14">15]</ref>. By using suffix trees and suffix arrays, all occurrences of a pattern can be reported in O(m + occ) and O(m log n + occ) time, respectively, where occ is the total number of occurrences of the pattern in the text.</p><p>Ehrenfeucht et al. <ref type="bibr" target="#b4">[5]</ref> proposed more space efficient indexing structure called position heaps, which requires O(n) space but the number of nodes in the position heaps is at most n + 1 although that of the suffix tree is at most 2n − 1.</p><p>Kucherov <ref type="bibr">[?]</ref> showed an Ukkonen-like on-line O(n)-time algorithm for constructing position heaps. By using position heaps, the occurrences of the pattern can be found in O(m 2 + occ) time. To improve its time bound to O(m + occ), Ehrenfeucht et al. <ref type="bibr" target="#b4">[5]</ref> proposed O(n)-space auxiliary structure, called the maximal-reach pointers (shortly MRPs).</p><p>Recently, Katsura et al. <ref type="bibr" target="#b7">[8]</ref> proposed a new framework of the string matching problem, called the permuted pattern matching for multi-track strings, that are multi-sets of strings. It can be applied to multiple sequence data such as polyphonic music data, multiple sensor data, and multiple genomes. Formally, two multi-sets of strings T = {t 1 , . . . , t N } and P = {p 1 , . . . , p N } are given, where |t k | = n and |p k | = m for 1 ≤ k ≤ N , and m ≤ n. P is said to permuted-match T at position i if there exists a permutation (j 1 , . . . , j N ) of a subsequence of (1, . . . , N ) such that p 1 = t j1 [i : i + m − 1], . . . , p N = t j N [i : i + m − 1], where t j [b : e] is the substring of t j from b to e. Then, the permuted pattern matching problem is to find all positions i that P permuted-matches T.</p><p>To solve this problem efficiently, Katsura et al. proposed an indexing structure for multi-track strings, called multi-track suffix trees (shortly MTST). MTST can be built in O(nN ) time and space, and it provides an O(mN + occ)-time matching algorithm. MTST has most 2n − 1 nodes.</p><p>Note that another well-known indexing structure generalized suffix tree (GST) is also applicable to the problem. By a natural extension, the matching can be done in O(mN +occ) time. The space complexity is also O(nN ), but the number of nodes is at most 2nN − 1.</p><p>In this paper, we propose two new memory efficient indexing structures for multi-track strings, multi-track position heap (MTPH) and contracted multi-track position heap (CMTPH).</p><p>CMTPH is a compact version of MTPH, where some nodes are rearranged and omitted. The number of nodes in MTPH and CMTPH is at most nN + 1 and n + 1, respectively, although the input size of the multi-track text is nN .</p><p>The permuted pattern matching using MTPH or CMTPH requires O(m 2 N + occ) or O(m 2 N 2 + occ) time, respectively. Moreover, for MTPH and CMTPH, we define the MRPs to accelarate the matching.</p><p>We show O(nN )-time construction algorithms for MTPH and CMTPH with their MRPs. The contributions of this paper is summarized in Table <ref type="table" target="#tab_0">1</ref>.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2">Preliminaries</head><p>Let Σ be a finite set of characters, called an alphabet. We assume that Σ is fixed throughout the paper. An element of Σ * is called a string. For two strings x and y, let x • y, or xy briefly, be the concatenation of x and y. For a string w = xyz, strings x, y, z are called prefix, substring, suffix of w, respectively. |w| is the length of w. The empty string is denoted by ε, that is |ε| = 0. w[i] is the i-th character of w, and w[i : j] is the substring of w that begins at position i and ends at j for 1</p><formula xml:id="formula_0">≤ i ≤ j ≤ |w|. Moreover, let w[: i] = w[1 : i] and w[i :] = w[i : |w|].</formula><p>We denote by x ≺ y if x is lexicographically smaller than y, and denote by x y if either x ≺ y or x = y. For a set S, we denote by |S| the cardinality of S.</p><p>An N -tuple<ref type="foot" target="#foot_0">1</ref> of strings over Σ of length n is called a multi-track string over Σ or simply multi-track.</p><p>For a multi-track T = (t 1 , t 2 , . . . , t N ) over Σ, the i-th element t i of T is called the i-th track, the length of multi-track T is denoted by</p><formula xml:id="formula_1">|T| len = |t 1 | = |t 2 | = • • • = |t N | = n,</formula><p>and the number of tracks in multi-track T or the track count of T, is denoted by |T| num = N . For two multi-tracks X = (x 1 , x 2 , . . . , x N ) and Y = (y 1 , y 2 , . . . , y N ), we say that X equals Y, denoted by X = Y, if x i = y i for all 1 ≤ i ≤ N .</p><p>For a multi-track T = XYZ, multi-track X, Y, and Z are called prefix, substring, and suffix of T, respectively.</p><formula xml:id="formula_2">T[i] denotes (t 1 [i], t 2 [i], . . . , t N [i]) for 1 ≤ i ≤ |T| len , i.e., T = T[1]T[2] . . . T[|T| len ].</formula><p>The substring of T that begins at position i and ends at position j is denoted by</p><formula xml:id="formula_3">T[i : j] = (t 1 [i : j], t 2 [i : j], . . . , t N [i : j]) for 1 ≤ i ≤ j ≤ |T| len . Moreover, let T[: i] = T[1 : i] and T[i :] = T[i : |T| len ],</formula><p>respectively.</p><p>Let X = (x 1 , x 2 , . . . , x N ) be a multi-track of track count N , and r = (r 1 , r 2 , . . . , r N ) be a permutation of (1, . . . , N ). A permuted multi-track of X specified by r is a multi-track (x r1 , x r2 , . . . , x r N ), denoted by either X r 1 , r 2 , . . . , r N or X r . For two multi-tracks X and Y, we say that X permuted-matches Y, denoted by X = Y, if X = Y for some permuted multi-track Y of Y. The problem we consider is defined as following:</p><p>Problem 1 (Permuted pattern matching). Given two multi-tracks T = (t 1 , t 2 , . . . , t N ) of length n and P = (p 1 , p 2 , . . . , p N ) of length m, output all positions i that satisfy</p><formula xml:id="formula_4">P = T[i : i + m − 1].</formula><p>For a multi-track X = (x 1 , x 2 , . . . , x N ), let SI (X) = (r 1 , r 2 , . . . , r N ) be a permutation such that x ri</p><p>x rj for any 1 ≤ i ≤ j ≤ |X| num , and let Ψ (X) = X SI (X) . All SI (T[i :]) for 1 ≤ i ≤ n and Ψ (T) can be computed in O(nN ) time using the suffix tree <ref type="bibr" target="#b15">[16]</ref> or the suffix array <ref type="bibr" target="#b10">[11]</ref>. It is known that the suffix tree and the suffix array can be constructed in linear time with respect to the length of the input string <ref type="bibr" target="#b5">[6,</ref><ref type="bibr" target="#b6">7,</ref><ref type="bibr" target="#b8">9,</ref><ref type="bibr" target="#b11">12,</ref><ref type="bibr" target="#b12">13,</ref><ref type="bibr" target="#b14">15]</ref>. Therefore, Problem 1 can be solved in O(nmN ) time and O(nN ) space by storing all SI (T[i :]) naively. The aim of this paper is to solve Problem 1 more efficiently than the above naive result.</p><p>A trie on Σ is a rooted tree that has the following two properties: (1) each edge is labeled by a character c ∈ Σ, and (2) for each node u and a character c ∈ Σ, u has at most one edge that is labeled by c from u to a child of u. Let T = (V, E) be a trie, where V and E are sets of nodes and edges, respectively. The root node of T is denoted by root. Each edge e ∈ E is denoted by (u, c, v), where c ∈ Σ is the label of e, and v is a child node of a node u. Note that the time required to find the child of a node on the child edge labeled by c ∈ Σ is O(log |Σ|). Because |Σ| is a fixed constant in this paper, so that the above time cost is also constant. For a node v ∈ V , the sequence of nodes and edges from root to v, that is root, e 1 , v 1 , e 2 , v 2 , . . . , e k , v, is called the path from root to v, denoted by path(root, v ). The number of edges on path(root, v ) is called the depth of v, denoted by depth(v). Let c i be the label of e i for i = 1, . . . , k. Then, we say that the string w = c 1 c 2 . . . c k is represented in T , and denote the node v by w and the string w by label (v).</p><p>Thus, root = ε and label (root) = ε. For any node v in T , the set of ancestors of v is denoted by Anc(v) and the descendants of v by Des(v).</p><p>A sequence hash tree <ref type="bibr" target="#b3">[4]</ref> is a trie for hashing a set of strings.</p><p>Definition 1 (Sequence hash trees <ref type="bibr" target="#b3">[4]</ref>). Let W = {w 1 , w 2 , . . . , w k } be an ordered set of strings, where</p><formula xml:id="formula_5">w i ∈ Σ * . For 1 ≤ i ≤ k, SHT i (W ) = (V i , E i ) is a trie recursively defined by (V 0 , E 0 ) = ({root}, ∅), and SHT i (W ) = (V i−1 ∪ {q i }, E i−1 ∪ {(q i [: |q i | − 1], c, q i )})</formula><p>, where q i is the shortest prefix of</p><formula xml:id="formula_6">w i satisfying q i / ∈ V i−1 , and c = q i [|q i |]. SHT k (W )</formula><p>is called a sequence hash tree of W and denoted by SHT (W ).</p><p>For any i, SHT i (W ) is obtained by adding at most one node and one edge. Thus,</p><formula xml:id="formula_7">SHT (W ) = SHT k (W ) consumes O(k) space. SHT i (W ) is obtained by adding a node corresponding to w i into SHT i−1 (W ). When the node correspond- ing to w i is added into SHT i−1 (W ), we say that w i is inserted to SHT i−1 (W ). Lemma 1. Let W = {w 1 , w 2 , . . . , w K } and W = {w 1 , w 2 , . . . , w k } (k ≤ K) be ordered sets of strings such that W is a subset of W . Then SHT (W ) is a subtree of SHT (W ) rooted by the root of SHT (W ).</formula><p>Proof. Let v be the node that is added to SHT (W ) when a string w ∈ W is inserted to SHT (W ), and let d = depth(v). Then there exist 1 ≤ i 1 &lt; i 2 &lt; . . . &lt; i d−1 ≤ k such that the strings w i1 , w i2 , . . ., w i d−1 precede w in W , and w ij [: j] = w[: j] holds for each 1 ≤ j ≤ d − 1. These strings also precede w in W , because W is a subset of W . Thus, w i1 , w i2 , . . . , w i d−1 , and w are inserted to SHT (W ) in this order. When w ij is inserted to SHT (W ), the node w[: j] is added to SHT (W ) if w[: j] does not exist in SHT (W ) for 1 ≤ j ≤ d−1. Therefore, when w is inserted to SHT (W ), w[: d − 1] has already been represented in SHT (W ) and w[: d] is added to SHT (W ). As a result, any string represented in SHT (W ) is also represented in SHT (W ), so that the statement holds.</p><p>We use the following results for the rooted tree T of n nodes and σ degree.</p><p>Lemma 2 (Lowest common ancestor query <ref type="bibr" target="#b13">[14,</ref><ref type="bibr" target="#b1">2]</ref>). For any given two nodes u and v, the lowest common ancestor LCA(u, v ) of u and v in T can be answered in O(1) time, after an O(n) time and space preprocessing of T .</p><p>Lemma 3 (Nearest marked ancestor query <ref type="bibr" target="#b16">[17,</ref><ref type="bibr" target="#b0">1]</ref>). For any given node v, both marking v, denoted by Mark (v ), and finding the nearest ancestor NMA(v ) of v that is marked, can be done in O(1) time, after an O(n log σ) time and O(n) space preprocessing of T .</p><p>Lemma 4 (Level ancestor query <ref type="bibr" target="#b2">[3]</ref>). For any given node v and an integer d &gt; 0, the ancestor LevA(v , d ) of v at depth d can be answered in O(1) time, after an O(n) time and space preprocessing of T . </p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3">Multi-Track Position Heaps</head><p>In this section, we propose a new data structure, named multi-track position heap (shortly MTPH), based on the sequence hash tree. We define a column concatenated string CS T of a multi-track T = (t 1 , t 2 , . . . , t N ) by</p><formula xml:id="formula_8">CS T = t 1 [1]t 2 [1] . . . t N [1] t 1 [2]t 2 [2] . . . t N [2] . . . t 1 [n]t 2 [n] . . . t N [n].</formula><p>For instance, for T = (abac, deba), we have CS T = adbeabca.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Definition 2 (MTPH).</head><p>Let T be a multi-track string of length n and track count N over Σ. Let s i,j = CS Ψ (T[i:j]) for 1 ≤ i ≤ j ≤ n, and s i,n is denoted by s i briefly. Let S = {s 1 , s 2 , . . . , s n } be an ordered set of the strings. For 1 ≤ i ≤ n, MTPH i (T) = (V i , E i ) is a trie recursively defined by (V 0 , E 0 ) = ({root}, ∅), and</p><formula xml:id="formula_9">V i = V i−1 ∪ ∆i−1 j=0 {s i [: |q i | + j]}, E i = E i−1 ∪ ∆i−1 j=0 {(s i [: |q i | + j − 1], s i [|q i | + j], s i [: |q i | + j])})</formula><p>, where q i is the shortest prefix of s i such that q i / ∈ V i−1 and q i = ε, and</p><formula xml:id="formula_10">∆ i = N − ((|q i | − 1) mod N ). If no such q i exists, that is s i ∈ V i−1 , then (V i , E i ) = (V i−1 , E i−1 )</formula><p>. MTPH n (T) is called a multi-track position heap of T, and denoted by MTPH (T). Figure <ref type="figure" target="#fig_0">1</ref> shows an example of MTPH (T) and column concatenated strings. Both the numbers of nodes and edges of MTPH i (T) increase at most N from MTPH i−1 (T) for each 1 ≤ i ≤ n. Thus, MTPH (T) consumes O(nN ) space. If there exists q i , then we associate the position i to the node s i [:</p><formula xml:id="formula_11">|q i | + ∆ i − 1],</formula><p>and call it an indexing node. Otherwise, that is s i ∈ V i−1 , we associate i to the node s i . Therefore, each indexing node stores either one or two positions. In case that an indexing node v stores two positions i and j with i &lt; j, we call that i is the primary position and j is the secondary position in v.</p><p>We will show that MTPH (T) can be constructed in O(nN ) time by updating MTPH (T[: i − 1]) to MTPH (T[: i]) iteratively for i = 1, 2, . . . , n, similar to the online construction algorithm for position heaps <ref type="bibr" target="#b9">[10]</ref>. We remark that it is not trivial because s i is not necessarily a suffix of s i−1 (see Figure <ref type="figure" target="#fig_0">1</ref>, left). Let us focus on the differences between MTPH (T[: i − 1]) and MTPH (T[: i]). For 1 ≤ j ≤ i, if j is a primary position in a node v in MTPH (T[: i − 1]), j must be the primary position stored in the same node v in MTPH (T[: i]). If j is a secondary position in MTPH (T[: i−1]), there are two cases in MTPH (T[: i]): (1) j becomes a primary position in a newly created node v , or (2) j remains the secondary position, but in another node v . In any case, the node v is in Des(v). Thus, we consider how to update the nodes storing two positions.</p><p>Let j (1 ≤ j &lt; i) be any secondary position in a node v in MTPH (T[: i − 1]). If the string s j,i is not represented in MTPH (T[: i − 1]) yet, then we create a new path path(root, s j ,i ) and reset the position j from v to a newly created node s j,i . Otherwise, the position j must be a secondary in another existing node v in MTPH (T[: i]). Thus, we should reset j from v to v = s j,i . These update process can be done by traversing the nodes storing the secondary positions.</p><p>We will show that for any position b (1 ≤ b &lt; i), if b is a secondary position then b + 1 is also a secondary position, by a series of lemmas as follows.</p><p>Lemma 5. For two multi-tracks</p><formula xml:id="formula_12">X = (x 1 , x 2 , . . . , x N ) and Y = (y 1 , y 2 , . . . , y N ), if Ψ (X) = Ψ (Y) then Ψ (X[2 :]) = Ψ (Y[2 :]). Proof. Trivial. Lemma 6. For any multi-track W of length m, if CS Ψ (W) is represented in MTPH i (T), then CS Ψ (W[2:]) is also represented in MTPH i (T) for any 1 ≤ i ≤ n. Proof. Because CS Ψ (W) is represented in MTPH i (T), there are 1 ≤ j 1 ≤ j 2 ≤ . . . ≤ j m ≤ i such that Ψ (T[j k : j k + k − 1]) = Ψ (W[: k]) for 1 ≤ k ≤ m,</formula><p>and they have been inserted to MTPH in the order of k = 1, 2, . . . , m. At the same time, Ψ (T[j k + 1 : j k + k − 1]) for 1 ≤ k ≤ m have also been inserted in this order, because MTPH is constructed by inserting suffixes in descending order with respect to the length. Lemma 5 leads Ψ (T[j k + 1 : ) should be updated as follows: (1) for b ≤ j &lt; b , build path(s j ,i−1 , s j ,i ) and reset the position j from s j,i−1 to the new node s j,i as its primary position, and (2) for b ≤ j ≤ i, reset the position j from s j,i−1 to the existing node s j,i as its secondary position. We refer the position b as the active position, and the indexing node s b,i−1 as the active node, similarly to [?]. The nodes storing positions b, b + 1, . . . , i − 1 can be traversed efficiently by using the suffix pointers defined below.</p><formula xml:id="formula_13">j k + k]) = Ψ (W[2 : k]). Thus, CS Ψ (T[jm+1:jm+m]) = CS Ψ (W)[2:] is represented in MTPH i (T ).</formula><p>Definition 3 (Multi-track suffix pointers). For any indexing node s i,j in MTPH (T), the multi-track suffix pointer of s i,j is a pointer from s i,j to the node s i+1,j , and denoted as mtsp(s i,j ) = s i+1,j .</p><p>For every indexing node s i,j in MTPH (T[: i]), the existence of mtsp(s i,j ) is guaranteed by Lemma 6. In our algorithm, we will use a chain of N nodes ⊥ 1 , ⊥ 2 , . . . , ⊥ N , such that each ⊥ k (1 ≤ k ≤ N ) is connected to ⊥ k+1 by an edge labeled by all c ∈ Σ, regarding that ⊥ N +1 = root, and mtsp(root) =⊥ 1 . They play a role of sentinel nodes, similarly to <ref type="bibr" target="#b14">[15]</ref> and <ref type="bibr">[?]</ref>.</p><p>We now describe the construction algorithm of MTPH (T). First of all, we compute SI (T[i : n]) for all 1 ≤ i ≤ n in O(nN ) time. It determines every</p><formula xml:id="formula_14">s i = CS Ψ (T[i:]) .</formula><p>In each iteration, we do not need to keep all the secondary nodes to update MTPH (T[: i − 1]), because these nodes can be visited through the suffix pointers recursively from the active node. Thus, we only maintain the active position b and the active node s b,i−1 . If there is no secondary node in MTPH (T[: i − 1]), the active node is root and the active position is i.</p><p>In i-th iteration, the algorithm checks whether there is path(s b,i−1 , s b,i ) or not. If it does not exist, the algorithm performs the modifications of Case (1) described above. After the modification, the new indexing node s b,i is created as a descendant of s b,i−1 . Then, the active position and the active node are updated to b + 1 and mtsp(s b,i−1 ) = s b+1,i−1 respectively, and the algorithm performs the above process iteratively until the path is found. The multi-track suffix pointer mtsp(s b,i ) is built as mtsp(s b,i ) = s b+1,i after the next modification. When path(s b,i−1 , s b,i ) is found, the algorithm updates the active node to s b,i and makes the suffix pointer from the last created indexing node to the new active node if such a node exists. Hence, for any indexing node, suffix pointer of it is defined indeed. To update MTPH (T[: i − 1]) into MTPH (T[: i]), it is enough to perform only the modifications of Case (1), because the modifications of Case (2) does not add any node nor edge to MTPH. All the secondary positions will be determined after constructing MTPH (T) by traversing nodes through the suffix pointers recursively from the active node.</p><p>Algorithm 1 shows a pseudo-code of the construction algorithm, and the function to find path(s b,i−1 , s b,i ) at line 26. Let us analyze the running time of Algorithm 1. Each iteration of the while-loop from line 9 takes O(nN ) time over the whole run of the algorithm, because at most N nodes and edges are visited or created in each iteration and 1 ≤ b ≤ n. Each process in the rest of the for-loop from line 6 takes at most O(N ) time, and the loop iterates exactly n times. Thus, the running time of Algorithm 1 is O(nN ) time. We now consider to solve Problem 1 for a pattern P by using MTPH (T). Let w be the longest prefix of CS Ψ (P) represented in MTPH (T). We can compute w in O(mN ) time by traversing path(root, w ). If w = CS Ψ (P) , all the positions stored in the nodes of the subtree rooted by w are the occurrences of the pattern P in T. We will deal with enumerating all these positions later. Before it, remark where pointerNode is the deepest indexing node visited in the i-th iteration and computed in line 5. Note that, the process of line 5 can be computed in constant time because whether currNode is an indexing node or not is determined by depth(currNode) mod N = 0 or not.</p><p>Let us consider the time complexity of Algorithm 2. Each process of line 1, line 7 and line 8 can be done in O(1) time, so that these processes take O(n) time in total. Let us consider the number of executions of while-loop at line 3. In each loop, s i [ ] corresponding to a letter in the text T is read. We assume s i [ i ] belongs to k-th column of T for 1 ≤ k ≤ n. k does not decrease between i-th and (i + 1)-th iterations because (i + 1)-th iteration begins at mtsp(s i,k ) = s i+1,k . In addition, since |s i [ i ]| ≥ N , i ≤ k holds. Thus, all letters in T are read at least one time in all iterations. On the other hand, the letters corresponding to the labels on path(pointerNode, currNode) in i-th iteration can be read redundantly in (i + 1)-th iteration. However, the number of such labels does not exceed N in each iteration. Therefore, the total number of executions of while-loop does not exceed 2nN . As a result, the running time of Algorithm 2 is O(nN ) time.</p><p>In the naive matching algorithm with MTPH described above, the cost of the comparison of CS Ψ (P) with s i,i+m−1 for i ∈ I can be reduced from O(mN ) to O(1) by using the MRPs and the lowest common ancestor queries mentioned in Lemma 4, if CS Ψ (P) itself is represented in MTPH (T). Whether CS Ψ (P) = s i,i+m−1 or not is determined by mrp(α i ) ∈ Des(CS Ψ (P) ). If LCA(mrp(α i ), CS Ψ (P) ) = CS Ψ (P) , then mrp(α i ) ∈ Des(CS Ψ (P) ) holds. By Lemma 4, the query LCA(mrp(α i ), CS Ψ (P) ) can be answered in O(1) time after an O(nN ) time and space preprocessing of MTPH (T). Thus, the comparison of CS Ψ (P) with s i,i+m−1 can be done in O(1) time. Hence, the total time is O(mN + occ) in this case, different from O(m 2 N + occ) time of the naive algorithm. Remark that, unfortunately, this result does not improve the upperbound of the time complexity of the matching for the worst case. If CS Ψ (P) is not represented in MTPH (T), we must compute CS Ψ (P) = s i,i+m−1 , that takes O(mN ) time. In this case, all comparisons are done in O(m 2 N ) time because |I| &lt; m. By considering the above two cases, the time bound of the matching is</p><formula xml:id="formula_15">O(mN + occ + m 2 N ) = O(m 2 N + occ).</formula><p>Theorem 2. Problem 1 can be solved in O(m 2 N +occ) time by using MTPH (T) with MRPs.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="4">Contracted Multi-Track Position Heaps</head><p>We propose a more space-efficient version of MTPH, by omitting non-indexing nodes of MTPH (see Figure <ref type="figure" target="#fig_0">1</ref>, right).</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Definition 5 (CMPTH).</head><p>Let T be a multi-track string of length n and track count N over Σ. Let S = {s 1 , s 2 , . . . , s n } be an ordered set of strings, where s i = CS Ψ (T[i:]) for 1 ≤ i ≤ n. A contracted multi-track position heap of T, denoted by CMTPH (T), is a sequence hash tree of S, i.e., CMTPH (T) = SHT (S).</p><p>Since CMTPH (T) is a sequence hash tree for an ordered set of cardinality n, it has n + 1 nodes and n edges, so that CMTPH (T) consumes only O(n) space. Given T, we can construct easily CMTPH (T) in O(nN + n 2 ) time as follows: compute SI (T[i :]) for 1 ≤ i ≤ n in O(nN ) time, then insert all s i = CS Ψ (T[i:]) to the tree in order; each insertion can be done in O(n), so that O(n 2 ) in total.</p><p>We now show a more efficient construction algorithm for CMTPH (T), that runs in O(nN ) time. It re-assign the positions in the nodes in MTPH (T), and eliminates all non-indexing nodes as follows. First let us noticed that in Figure <ref type="figure" target="#fig_0">1</ref>, CMTPH (T) is a subtree of MTPH (T) with the same root node, if we ignore the positions stored in the nodes. It is always the cases, as follows.</p><p>Lemma 8. For 1 ≤ i ≤ n, CMTPH i (T) is a subtree of MTPH i (T) rooted by the root of MTPH i (T), if we ignore the positions stored in the nodes.</p><p>Proof. CMTPH i (T) is a sequence hash tree of S = {s 1 , s 2 , . . . , s i }. On the other hand, MTPH i (T) is equivalent to a sequence hash tree of S = i k=1</p><formula xml:id="formula_16">∆ k j=1 {s k } = {s 1 , . . . , s 1 ∆1 , s 2 , . . . , s 2 ∆2 , . . . , s i , . . . , s i ∆i }.</formula><p>Because S is a subset of S , the statement holds by Lemma 1.</p><p>Lemma 8 implies that all nodes and edges in CMTPH (T) are included in MTPH (T). Therefore, CMTPH (T) can be obtained by the following process. For each i = 1, 2, . . . , n, we re-assign the position i stored in an indexing node α i to its ancestor node β i ∈ Anc(α i ), that does not store the primary position (i.e., β i may store the secondary position) and the farthest from α i (i.e., nearest from the root). If there is no such a node, then α i keeps storing i. After that, we eliminate all nodes that stores no position. Then, the remaining tree is CMTPH (T).</p><p>To find β i efficiently, we use the two types of queries on a rooted tree, that are the nearest marked ancestor query and the level ancestor query referred in Lemma 3 and Lemma 4, respectively. Each query can be answered in constant time after a linear-time preprocess of the tree.</p><p>We now show how to find β i from α i . We mark a node to indicate that the node stores some positions in CMTPH (T). At the beginning, only the root of MTPH (T) is marked. Because β i is the farthest unmarked ancestor of α i , it is the depth d + 1 ancestor of α i , where d is the depth of the nearest marked ancestor u of α i . The ancestor u is obtained by NMA(α i ), and then β i by LevA(u, depth(u) + 1 ), both in O(1) time. If u = α i , re-assign the position i from α i to β i , and mark β i . Otherwise, i.e., u = α i , do nothing. Repeating it for i = 1, 2, . . . , n, we get CMTPH (T) in O(n) time from MTPH (T). Because MTPH (T) can be constructed in O(nN ) time, we obtain the following result. CMTPHs is useful for permuted pattern matching instead of MTPHs. Because any node in CMTPH stores at least one position, the candidate positions for matching is at most |I| = O(mN ). Thus, the time complexity is O(m 2 N 2 + occ). It can be improved by using the maximal-reach pointers for CMTPH, denoted by cmrp(β i ), in the same way as MTPH. Because cmrp(β i ) = NMA(mrp(α i )) holds for any i after marking all β i 's, we get them in O(n) time. Thus we have the following results. For the permuted pattern matching, the maximal-reach pointers of CMTPH work similarly to that of MTPH. Thus, it is not difficult to see that the following theorem holds.</p><p>Theorem 5. Problem 1 can be solved in O(m 2 N 2 + occ) time by using CMTPH (T) with the maximal-reach pointers.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="5">Conclusion and Future Work</head><p>We proposed two new indexing structures, MTPH and CMTPH, for multi-track strings, that are memory-efficient compared with the multi-track suffix tree in <ref type="bibr" target="#b7">[8]</ref>; MTPH and CMTPH need O(nN ) and O(n) space, respectively. We showed an O(nN )-time construction algorithms of MTPH and CMTPH, and proposed MRPs for both of them. By using these data structures, the permuted pattern matching problem can be solved efficiently: O(m 2 N + occ) time by MTPH, and O(m 2 N 2 + occ) time by CMTPH. Our future work is to construct CMPTH directly in O(nN ) time without constructing MTPH. We are also preparing experiments to evaluate these structures.</p></div><figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_0"><head>Fig. 1 .</head><label>1</label><figDesc>Fig. 1. The column concatenated strings si = CS Ψ (T[i:]) in the left, MTPH (T) in the middle, and CMTPH (T) in the right for a multi-track T = (aabbaabbaaabbaa, ababababbababba). Maximal-reach pointers mrp(v) in MTPH and CMTPH are drawn as broken lines, where they are omitted if mrp(v) = v for clarity. In indexing nodes, its associated positions (either one or two) are written.</figDesc><graphic coords="5,137.60,115.84,340.15,132.39" type="bitmap" /></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_1"><head>Lemma 7 .</head><label>7</label><figDesc>If b is a secondary position of a node v in MTPH i (T) for 1 ≤ b &lt; i, then b + 1 is also a secondary position of another node in it. Proof. Let b be the primary position of v. Then, b &lt; b and s b = s b [: |s b |] hold. From Lemma 6, s b+1 is represented in MTPH i (T). In addition, s b +1 [: |s b+1 |] is also represented. From Lemma 5, s b+1 = s b +1 [: |s b+1 |] holds. Since b &lt; b, b + 1 &lt; b + 1. Thus, b + 1 is a secondary position of s b +1 . Let b be the smallest position that is a secondary position in MTPH (T[: i−1]) with 1 ≤ b ≤ i − 1. By Lemma 7, all the secondary positions are written as b, b + 1, . . . , i − 1. In addition, these positions are partitioned into two intervals. Let b be the smallest position such that s b ,i is represented in MTPH (T[: i − 1]). Then, s b +1,i is also represented in it by Lemma 6. Similarly, all s b +2,i , . . . , s i−1,i are represented in it, too. Therefore, all the positions b, b+1, . . . , b −1 in the first interval are primary positions in MTPH (T[: i]), while all b , b + 1, . . . , i − 1 in the second interval are secondary positions in MTPH (T[: i]). Summarizing the above discussion, to obtain MTPH (T[: i]), MTPH (T[: i − 1]</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_2"><head>Theorem 1 .</head><label>1</label><figDesc>Algorithm 1 constructs MTPH (T) in O(nN ) time and space.</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_3"><head>Theorem 3 .</head><label>3</label><figDesc>Given a multi-track T of length n and track count N , CMTPH (T) can be constructed in O(nN ) time and space.</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_4"><head>Theorem 4 .</head><label>4</label><figDesc>Given a multi-track T of length n and track count N , CMTPH (T) with the maximal-reach pointers for CMTPH (T) can be constructed in O(nN ) time and space.</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" type="table" xml:id="tab_0"><head>Table 1 .</head><label>1</label><figDesc>Data structures for the permuted pattern matching</figDesc><table><row><cell>data structure</cell><cell cols="3">space # of nodes construction</cell><cell>search</cell></row><row><cell>GST</cell><cell cols="2">O(nN ) 2nN − 1</cell><cell>O(nN )</cell><cell>O(mN + occ)</cell></row><row><cell>MTST [8]</cell><cell cols="2">O(nN ) 2n − 1</cell><cell>O(nN )</cell><cell>O(mN + occ)</cell></row><row><cell cols="3">MTPH (proposal) O(nN ) nN + 1</cell><cell>O(nN )</cell><cell>O(m 2 N + occ)</cell></row><row><cell cols="2">CMTPH (proposal) O(n)</cell><cell>n + 1</cell><cell>O(nN )</cell><cell>O(m 2 N 2 + occ)</cell></row></table></figure>
			<note xmlns="http://www.tei-c.org/ns/1.0" place="foot" n="1" xml:id="foot_0">A multi-track string was regarded as a multi-set of strings in<ref type="bibr" target="#b7">[8]</ref>. In this paper, however, we define it as a tuple of strings for notational convenience.</note>
		</body>
		<back>
			<div type="annex">
<div xmlns="http://www.tei-c.org/ns/1.0"><p>We now explain how to enumerate all the positions in the nodes of the subtree rooted by w, in case that w = CS Ψ (P) . Let α i be an indexing node that stores the position i in MTPH (T). To obtain these positions efficiently in O(occ) time, we construct another tree T consists only of indexing nodes α i 's in MTPH (T), where a node α i is a child of another node α j in T if and only if α i ∈ Des(α j ) and no other indexing node exists between α i and α j in MTPH (T). Obviously, T can be built by depth-first-traversal of MTPH (T) in O(nN ) time, and by traversing the subtree of T rooted by the node w, we can enumerate all matched positions in O(occ) time. Thus, we can determine all the positions i such that</p><p>We now show that the matching by using MTPH can be accelerated by adding maximal-reach pointers (shortly MRPs). MRPs are the auxiliary structures for standard position heaps proposed by Ehrenfeucht et al. <ref type="bibr" target="#b4">[5]</ref>. We will extend it to MTPHs as follows.</p><p>Definition 4 (MRPs for MTPHs). For an indexing node α i storing i in MTPH (T), the maximal-reach pointer of α i is a pointer from α i to s i [: i ], and denoted by mrp</p><p>Algorithm 2 is an algorithm for adding MRPs to MTPH, that is based on Kucherov's algorithm for standard position heaps <ref type="bibr">[?]</ref>. First of all, the algorithm preprocesses MTPH (T) so that for any node v, it can obtain the depth of v in O(1) time, by assigning unique numbers to the nodes by the depth first traversal. In i-th iteration between line 2 and line 8, it adds a pointer mrp(α i ) = s i [: i ], where s i [: i ] is determined as follows: beginning by currNode = root, it goes down to a child s i [: ] of depth(currNode) ≤ ≤ |s i | until either currNode does not have a child s i [: ] or = |s i | holds (line 3 to line 6). Then, mrp(α i ) is obtained as s i [: i ] (line 7). The next i+1-th iteration begins at mtsp(pointerNode),</p></div>			</div>
			<div type="references">

				<listBibl>

<biblStruct xml:id="b0">
	<analytic>
		<title level="a" type="main">Improved dynamic dictionary matching</title>
		<author>
			<persName><forename type="first">A</forename><surname>Amir</surname></persName>
		</author>
		<author>
			<persName><forename type="first">M</forename><surname>Farach</surname></persName>
		</author>
		<author>
			<persName><forename type="first">R</forename><forename type="middle">M</forename><surname>Idury</surname></persName>
		</author>
		<author>
			<persName><forename type="first">J</forename><forename type="middle">A L</forename><surname>Poutre</surname></persName>
		</author>
		<author>
			<persName><forename type="first">A</forename><forename type="middle">A</forename><surname>Schäffer</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">Information and Computation</title>
		<imprint>
			<biblScope unit="volume">119</biblScope>
			<biblScope unit="issue">2</biblScope>
			<biblScope unit="page" from="258" to="282" />
			<date type="published" when="1995">1995</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b1">
	<analytic>
		<title level="a" type="main">The LCA problem revisited</title>
		<author>
			<persName><forename type="first">M</forename><forename type="middle">A</forename><surname>Bender</surname></persName>
		</author>
		<author>
			<persName><forename type="first">M</forename><surname>Farach-Colton</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">LATIN 2000: Theoretical Informatics</title>
				<imprint>
			<date type="published" when="2000">2000</date>
			<biblScope unit="page" from="88" to="94" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b2">
	<analytic>
		<title level="a" type="main">The level ancestor problem simplied</title>
		<author>
			<persName><forename type="first">M</forename><forename type="middle">A</forename><surname>Bender</surname></persName>
		</author>
		<author>
			<persName><forename type="first">M</forename><surname>Farach-Colton</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">Theoretical Computer Science</title>
		<imprint>
			<biblScope unit="volume">321</biblScope>
			<biblScope unit="issue">1</biblScope>
			<biblScope unit="page" from="5" to="12" />
			<date type="published" when="2004">2004</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b3">
	<analytic>
		<title level="a" type="main">File structures using hashing functions</title>
		<author>
			<persName><forename type="first">Jr</forename><surname>Coffman</surname></persName>
		</author>
		<author>
			<persName><forename type="first">E</forename><forename type="middle">G</forename><surname>Eve</surname></persName>
		</author>
		<author>
			<persName><forename type="first">J</forename></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">Communications of the ACM</title>
		<imprint>
			<biblScope unit="volume">13</biblScope>
			<biblScope unit="issue">7</biblScope>
			<biblScope unit="page" from="427" to="432" />
			<date type="published" when="1970">1970</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b4">
	<analytic>
		<title level="a" type="main">Position heaps: A simple and dynamic text indexing data structure</title>
		<author>
			<persName><forename type="first">A</forename><surname>Ehrenfeucht</surname></persName>
		</author>
		<author>
			<persName><forename type="first">R</forename><forename type="middle">M</forename><surname>Mcconnell</surname></persName>
		</author>
		<author>
			<persName><forename type="first">N</forename><surname>Osheim</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><forename type="middle">W</forename><surname>Woo</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">Journal of Discrete Algorithms</title>
		<imprint>
			<biblScope unit="volume">9</biblScope>
			<biblScope unit="issue">1</biblScope>
			<biblScope unit="page" from="100" to="121" />
			<date type="published" when="2011">2011</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b5">
	<analytic>
		<title level="a" type="main">Optimal suffix tree construction with large alphabets</title>
		<author>
			<persName><forename type="first">M</forename><surname>Farach</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">FOCS</title>
		<imprint>
			<biblScope unit="page" from="137" to="143" />
			<date type="published" when="1997">1997</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b6">
	<analytic>
		<title level="a" type="main">Simple linear work suffix array construction</title>
		<author>
			<persName><forename type="first">J</forename><surname>Kärkkäinen</surname></persName>
		</author>
		<author>
			<persName><forename type="first">P</forename><surname>Sanders</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">ICALP</title>
		<imprint>
			<biblScope unit="page" from="943" to="955" />
			<date type="published" when="2003">2003</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b7">
	<analytic>
		<title level="a" type="main">Permuted pattern matching on multi-track strings</title>
		<author>
			<persName><forename type="first">T</forename><surname>Katsura</surname></persName>
		</author>
		<author>
			<persName><forename type="first">K</forename><surname>Narisawa</surname></persName>
		</author>
		<author>
			<persName><forename type="first">A</forename><surname>Shinohara</surname></persName>
		</author>
		<author>
			<persName><forename type="first">H</forename><surname>Bannai</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Inenaga</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">SOFSEM</title>
		<imprint>
			<biblScope unit="page" from="280" to="291" />
			<date type="published" when="2013">2013</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b8">
	<analytic>
		<title level="a" type="main">Space efficient linear time construction of suffix arrays</title>
		<author>
			<persName><forename type="first">P</forename><surname>Ko</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Aluru</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">CPM</title>
		<imprint>
			<biblScope unit="page" from="200" to="210" />
			<date type="published" when="2003">2003</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b9">
	<analytic>
		<title level="a" type="main">On-line construction of position heaps</title>
		<author>
			<persName><forename type="first">G</forename><surname>Kucherov</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">Journal of Discrete Algorithms</title>
		<imprint>
			<biblScope unit="volume">20</biblScope>
			<biblScope unit="page" from="3" to="11" />
			<date type="published" when="2013">2013</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b10">
	<analytic>
		<title level="a" type="main">Suffix arrays: a new method for on-line string searches</title>
		<author>
			<persName><forename type="first">U</forename><surname>Manber</surname></persName>
		</author>
		<author>
			<persName><forename type="first">G</forename><surname>Myers</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">SIAM Journal on Computing</title>
		<imprint>
			<biblScope unit="volume">22</biblScope>
			<biblScope unit="issue">5</biblScope>
			<biblScope unit="page" from="935" to="948" />
			<date type="published" when="1993">1993</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b11">
	<analytic>
		<title level="a" type="main">A space-economical suffix tree construction algorithm</title>
		<author>
			<persName><forename type="first">E</forename><forename type="middle">M</forename><surname>Mccreight</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">Journal of the ACM</title>
		<imprint>
			<biblScope unit="volume">23</biblScope>
			<biblScope unit="issue">2</biblScope>
			<biblScope unit="page" from="262" to="272" />
			<date type="published" when="1976">1976</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b12">
	<analytic>
		<title level="a" type="main">Linear suffix array construction by almost pure induced-sorting</title>
		<author>
			<persName><forename type="first">G</forename><surname>Nong</surname></persName>
		</author>
		<author>
			<persName><forename type="first">S</forename><surname>Zhang</surname></persName>
		</author>
		<author>
			<persName><forename type="first">W</forename><forename type="middle">H</forename><surname>Chan</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">DCC</title>
		<imprint>
			<biblScope unit="page" from="193" to="202" />
			<date type="published" when="2009">2009</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b13">
	<analytic>
		<title level="a" type="main">On finding lowest common ancestors: Simplification and parallelization</title>
		<author>
			<persName><forename type="first">B</forename><surname>Schieber</surname></persName>
		</author>
		<author>
			<persName><forename type="first">U</forename><surname>Vishkin</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">SIAM Journal on Computing</title>
		<imprint>
			<biblScope unit="volume">17</biblScope>
			<biblScope unit="issue">6</biblScope>
			<biblScope unit="page" from="1253" to="1262" />
			<date type="published" when="1988">1988</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b14">
	<analytic>
		<title level="a" type="main">On-line construction of suffix trees</title>
		<author>
			<persName><forename type="first">E</forename><surname>Ukkonen</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">Algorithmica</title>
		<imprint>
			<biblScope unit="volume">14</biblScope>
			<biblScope unit="issue">3</biblScope>
			<biblScope unit="page" from="249" to="260" />
			<date type="published" when="1995">1995</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b15">
	<analytic>
		<title level="a" type="main">Linear pattern matching algorithms</title>
		<author>
			<persName><forename type="first">P</forename><surname>Weiner</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">SWAT</title>
		<imprint>
			<biblScope unit="page" from="1" to="11" />
			<date type="published" when="1973">1973</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b16">
	<analytic>
		<title level="a" type="main">Fast incremental planarity testing</title>
		<author>
			<persName><forename type="first">J</forename><surname>Westbrook</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="j">ICALP</title>
		<imprint>
			<biblScope unit="page" from="342" to="353" />
			<date type="published" when="1992">1992</date>
		</imprint>
	</monogr>
</biblStruct>

				</listBibl>
			</div>
		</back>
	</text>
</TEI>
