Dynamic Succinct Ordered Trees - Semantic Scholar

2 downloads 0 Views 153KB Size Report
sult on ordinal trees achieves only sublinear amortized update time and. “poly-log-log” query time [3]. 1 Introduction. A succinct representation of a combinatorial ...
Dynamic Succinct Ordered Trees Arash Farzan and J. Ian Munro {afarzan,imunro}@cs.uwaterloo.ca Cheriton School of Computer Science, University of Waterloo

Abstract. We study the problem of maintaining a dynamic tree succinctly, in 2n + o(n) bits, under updates of the following form: insertion or deletion of a leaf, insertion of a node on an edge (edge subdivision) or deletion of a node with only one child (the child becomes a child of the grandparent). We allow satellite data of a fixed (but not necessarily constant) size to be associated to the nodes of the tree. We support update operations in constant amortized time and support access to satellite data and basic navigation operations in worstcase constant time; the basic navigation operations includes parent, first/last-child, previous/next-child. We demonstrate that to allow fast support for more extended operations such as determining the i-th child of a node, rank of a child among its siblings, or subtree size, we require a restrictive update strategy for which we propose the fingerupdate model where updates are performed by a finger which is only allowed to crawl on the tree (between a child and a parent or between consecutive siblings). Under this model, we describe how the named operations can be performed in worst-case constant time. Previous work on dynamic succinct ordered trees [1, 2] is mainly restricted to binary trees and achieves poly-logarithmic [1] or “poly-loglog” [2] update time under a more restricted model. Best previous result on ordinal trees achieves only sublinear amortized update time and “poly-log-log” query time [3].

1

Introduction

A succinct representation of a combinatorial object is an encoding which supports a reasonable set of operations on the object in constant time and has a storage requirement matching the information theoretic lower bound, to within lower order terms. Succinct data structures perform under the uniform-time word-RAM model with Θ (lg n) word size. Ordered trees are trees in which the order of children of nodes is significant and preserved. Ordered trees, as a fundamental data structure, have attracted a great deal of research on their succinct representation [4–10]. All such approaches achieves the information-theory lower bound of 2n bits (to within lower order terms) to encode an ordered tree with n nodes, and their difference is in what queries they support.

The main drawback with most of the succinct tree representations is their lack of flexibility to allow dynamic updates, which necessitates an entire structure rebuild on modifications. Storm [11] in his thesis gives some main obstacles in dynamising the previously existing approaches and introduces a new succinct representation for binary trees allowing updates in poly-logarithmic time [1]. Raman and Rao [2] improve updates to poly-log-log time for binary trees. Gupta et al. [3] propose a framework for dynamising various succinct structures which, when applied to ordered trees, results in a dynamic succinct representation that performs updates in O (nǫ ) time for any constant ǫ > 0 and performs basic navigation queries in O (log log n) time. Arroyuelo [12] proposes a dynamic succinct structure for cardinal trees. A recent decomposition-based approach exists [10] to represent static ordered trees which greatly simplifies the encoding of trees and implementation of many operations on such trees. This paper demonstrates that the approach is of use in attaining a dynamic succinct representation of ordered trees which allows fast updates and operations. 1.1

Overview of the results

We use the general representation approach of [10] and show how to maintain the representation under insertions and deletions. The type of insertions and deletions supported is the same as in [1, 2] and are as follows: insertion or deletion of a leaf, insertion of a node with one child on an edge or deletion of a node with only one child (by connecting its parent to its child directly). Basic navigation operations which we support permit crawls on trees and include parent, first-child, last-child, previous-child, and next-child operations. These are supported in worst-case constant time. We note that these operations subsume the parent, left-child, and right-child operations in binary trees supported in previous work [1, 2]. Associated with each node v is a piece of data of length b bits (b = O (log n)). Given a node v, we support operations access-data(v) and change-data(v) in worst-case constant time. We show that, to support more advanced operations, one needs to restrict the pattern of updates. The operations, we consider, are child(v, i) which returns the i-th child of a given node v, child-rank(v) which returns the rank of a given node v among its siblings, and subtree-size(v) which returns the number of descendants of a given node v. child(v,i), child-rank(v) are two natural operations to consider as we move from binary trees to ordered trees where nodes can have arbitrary large degrees. The subtree-size(v) operation was considered and supported by previous work on dynamic binary trees [1, 2] using the traversal pattern for update. Under the traversal pattern updates are performed during the course of a traversal which starts at the root and ends at the root and subtree-size queries can be answered only on completion of the traversal. We relax the update pattern by introducing the finger-update model. In the finger-update model, there is a finger maintained on a node of the tree which

is initially on the root and it can move from a parent to the leftmost or the rightmost child or can move from a node to its immediate next or previous siblings. Updates are only allowed on the node currently under the finger. Any number of updates can be performed as the finger crawls on the tree and queries (such as subtree-size) can be asked at any time at any node. Updates are supported in amortized constant time over the number of movements of the finger and the number of updates performed. In the course of showing support for these operations, we design a partial-sum data structure which works optimally in the finger-update model. This structure is very useful and is of independent interest.

2

Succinct Representation

It is shown in [10] how an ordered tree with n nodes can be decomposed into n/L subtrees of size roughly L for any value of parameter L. Strictly speaking: Theorem 1. [10] A tree with n nodes can be decomposed into Θ (n/L) subtrees of size at most 2L which are pairwise disjoint aside from the subtree roots. Furthermore, aside from edges stemming from the subtree root nodes, there is at most one edge leaving a node of a component to its child in another component. The representation that we use is analogous to the static representation of [10]. It is based on a two-level recursive decomposition of a given tree. In the first level of the tree with n nodes is decomposed into subtrees us recursion,  ing value L = lg2 n , and subsequently these subtrees are, in turn, decomposed into yet smaller subtrees using value L = ⌈(lg n) /16⌉ to obtain the subtrees on the second level of recursion. Using the standard terminology of [8], we refer to the subtrees on the first level by mini-trees and the second level by micro-trees. Micro-trees of size less than ⌈(lg n) /8⌉ are small enough to be represented by a look-up table. The representation of a micro-tree with k nodes consists of two fields: the first field simply is the size of the micro-tree (O (log k) = O (lg lg n) bits) and the second field is an index to the look-up table (2k bits). These indices sum up to 2n bits over all micro trees and are the dominant term in our representation; other auxiliary data amounts to o (n) bits. The table stores encodings of all trees with sizes up to ⌈(lg n) /8⌉ along with answers to variety of queries types for each such tree. For all possible updates, each tree contains a pointer to the destination tree, i.e. the tree resulting from the application of that update. The size of the auxiliary data for each tree will be poly-logarithmic in n and thus the size of the entire table is o (n). Mini-trees consist of micro-trees and links between them. Links between different micro-trees can be in either of the three following forms: 1) a common root node, 2) edges from a single-node micro-tree to its children micro-tree or 3) an edge from a non-root node from a micro-tree to the root of another micro-tree. We represent the latter edges by introducing a dummy node on them. Due to the manner in which the tree is decomposed, there is at most one such edge leaving a non-root node in a micro-tree and hence, at most one dummy node in each

micro-tree. We keep explicit pointers (of size O (log log n)) to represent dummy edges, which are edges from dummy nodes to their children. To represent a common root among micro-trees, or edges emanating from a single-vertex micro-tree, we use explicit O (log log n)-bit pointers to form a doubly-linked list on sibling micro-trees such that two consecutive micro-trees on the chain contain two immediate sibling children of the root. This is in contrast to the use of dictionary structures in [10], as there is no dynamic dictionary structure with the desired functionalities. The linked list does not facilitate random accesses to children of a node, and we can overcome this issue by introducing a substitute structure that supports fast updates under the finger-update model in section 5.3. The tree consists of mini-trees and links between them. The tree over minitrees is represented analogously to the mini-tree representation over micro-trees: i.e. explicit pointers for edges coming out of mini-trees from non-root nodes and explicit O (log n)-bit pointers to reference left and right sibling mini-trees.

3

Performing updates

In this section, we show how the succinct structure of section 2 is maintained under insertions and deletions of nodes. To allow for dynamic updates, we relax the maximum size of a micro-tree to be ⌈(lg n) /4⌉ which is twice the maximum size we allowed in the static Analogously, we allow the maximum  representation.  size of a mini-tree to be 4 lg2 n , twice the maximum mini-tree size in the static representation. When a node is inserted or deleted, the topology of the corresponding micro-tree changes. The look-up table which lists all trees of size up to ⌈(lg n) /4⌉, also contains, for each tree and all possible insertions and deletions on the tree, the reference to the resulting tree under the update. Therefore, the update can be performed in constant time, provided the size of the corresponding micro-tree or mini-tree does not exceed the limits. When a micro-tree exceeds the maximum size, it is decomposed into (at most 4) subtrees using theorem 1 with value L = ⌈(lg n) /16⌉. The decomposition is performed in constant time using the look-up table: each entry of maximum size in the look-up table contains its decomposition information. Some of the newly created micro-trees resulted from the micro-tree decomposition could be undersized. However, we can charge them to the Θ (log n) insertions that made the original micro-tree  exceed over limits. Since we rebuild the containing minitree after O log2 n such insertions, there are O (log n) undersized micro-trees at any point and the representation remains valid. Analogously, when a mini-tree exceeds the maximum mini-tree size,  it is decomposed into (at most 4) subtrees using theorem 1 with value L = lg2 n .  The decomposition is performed in Θ log2 n time which is amortized over the  Θ log2 n insertions which brought the mini-tree over the limits. Some of the  newly created mini-trees could be undersized. We charge these to the Θ log2 n insertions which caused the mini-tree to overflow. As we rebuild the entire tree after n insertions, there are O n/ log2 n such undersized mini-trees at any point

and hence the representation remains valid. Together with creation of a minitree, micro-trees inside it are recomputed and represented. Handling of deletions from micro-trees and mini-trees is easier. No particular action is required to the point that the micro-tree or the mini-tree being deleted from becomes empty. In this event, the corresponding entries are removed from the representation. The entry removal costs Θ (log n) time for a micro-tree and  Θ log2 n for a mini-tree. These costs are amortized over the deletions that emptied the micro-tree or mini-tree. This is justified if the micro-tree or the mini tree are not undersized and have sizes Θ (log n) and Θ log2 n respectively. If the original mini-tree or micro-tree are undersized, they are either created as a result of a split or they were initially undersized before  any updates. In the former case, we showed there are Θ (log n) and Θ log2 n insertions which push the microtree or the mini-tree over limits, we charge these insertions instead. In the latter  case, a one-time linear fund of Θ (log n) for each micro-tree and Θ log2 n for each mini-tree is enough to deal with deletions of these components. One crucial part of dealing with updates is memory management. Microtrees and mini-trees grow and shrink as a result of insertions and deletions, and new ones are created as a result of splits, and they disappear when they become empty. We show in section 3.1 how these structures are handled in memory. 3.1

Memory management

Following the path of previous work [2], we assume the memory model in which the working space of the algorithm is from word 0 to the highest word h the algorithm is using at the time, and the space usage at any given time is the highest word being used. In the work of Munro et al. [1], they insist on having blocks and subblocks sit on a continuous segment of memory. We completely revise the memory management part of the structure to obtain constant amortized update time. We relax the requirement that mini/micro trees be stored in a continuous segment of memory; each may be spread over many segments. Mini trees are stored in blocks of memory and micro trees are stored in subblocks of memory. Each block consists of many continuous memory chunks called blocklets and similarly, each subblock consists of many continuous memory chunks called subblocklets.  Subblock memory management. Within a mini tree (of size Θ log2 n ), there  are Θ (log n) micro trees (of size Θ (log n)). Therefore, a block of size O log2 n consists of O (log n) subblocks of size O (log n). As depicted in figure 1, a block is divided into two areas: a clean area containing the main portion of subblocks and an overflow area of lg3/2 n bits which contains the overflow portion of subblocks that have overflown. Occasionally, once enough updates have been performed, the entire structure is rebuilt: everything is moved to the clean area and the overflow area is emptied. A subblock can be spread over two subblocklets: one in the main area and the other one in the overflow area. Each subblock has a header which contains

Clean area

O(lg n)

O(lg n)

Overow area

O(lg n)



log n



log n



log n

lg3/2 n bits

Fig. 1. Subblock layout within a block

a table of (two) references to the subblocklets and their sizes. This subblock reference table is used to resolve a memory address within a subblock. There are only two O (log log n)-bit pointers to store and the size of each blocklets can be stored in O (log log n) bits and the space overhead is negligible. We first explain how we handle insertions. We keep the count of the number 1 lg n insertions. The of insertions and rebuild the entire structure at every 16 √ 3/2 overflow area has lg n bits which are allocated in chunks of lg n bits. If √ a subblocklet in the clean area overflows, a lg n-bit chunk is allocated as the second subblocklet and the subblock reference table is updated accordingly. If the subblocklet in the overflow area becomes full, we must allocate another chunk to the subblock. As we require this chunk to be the immediate following chunk, we may have to move several following chunks if they belong to the same subblocklet to the end of the allocated chunks in the overflow area. Moreover, the references to these chunks must √ be updated accordingly in the subblock’s reference table. Moving takes O log n time in the worst case if the entire overflow area must √ be moved. This cost can be amortized over the O log n insertions in the overflowing subblocklet. Therefore, the amortized time is constant. When the overflow area is full, we rebuild the entire block and the overload area is emptied. This takes O (log n) time which can be amortized over O (log n) insertions that filled up the overflow area. Thus far, we have dealt only with insertions which cause subblocks to overflow. However, nodes can be deleted and as a result subblocks shrink. Deletions are easier to handle. We keep a count of the number of deletions in a block and 1 if they go over 48 lg n, we rebuild the entire block1 . The key observation is that since there has been O (log n) deletions since last rebuilt, the structure remains dense enough. Block memory management. In the previous section, we explained how subblocks are organized within an individual block. In this section, we explain how blocks are fragmented and laid out in memory. An outline of the memory layout is depicted in figure 2. At the block level, memory is allocated in chunks of lg3/2 n bits; when a block outgrows its allocated space a chunk of lg3/2 n bits at the end  of the currently used space is allocated for it. Since the block takes Θ log2 n bits and chunks 1

1 Constants such as 48 are chosen to make things work either by keeping table sizes sublinear or to allow for growth and contraction of substructures

lg3/2 n

lg3/2 n

lg3/2 n

lg 3/2 n

√ O( lg n) entries Blo k 1 referen e table

Fig. 2. Block memory layout: memory blocklets relative to a same block are not necessarily in a consecutive zone

 √ are lg3/2 n bits, a block consists of Θ log n chunks (i.e. blocklets). Thus, a table can be stored for each block which keeps tracks of pointers to blocklets of a block. We refer to this table as block reference table. Since blocklets have the same size, addressing inside a block using the block reference table is easy. Deletions are easier to deal with; We only keep a count of the number of deletions and if it exceeds n/ lg n, we compactify and rebuild the entire structure. Since, there can only be n/ lg n deleted nodes (and thus bits) in the structure, it remains dense enough. Furthermore, we can have keys and satellite data associated with each nodes and manage them efficiently in memory upon insertions and deletions. Due to lack of space, we defer the detailed discussion of this subject to a full version of this paper.

4

Navigation queries

In this section, we explain how the basic navigation operations are supported. The basic navigational operations are parent (parent), leftmost/rightmost child (first/last-child) and right/left siblings (previous/next-child). More enhanced operations such as i-th child of a node are to be discussed in section 5. We note that previous work [1, 2] functions only on binary trees and our basic navigation operations (leftmost child, right sibling) supports all of their supported navigational operations. We recall that the tree decomposition of [10] guarantees that each component subtree C has at most one edge going out of the component with the exception of the root of the component which can be shared by many components or can have many edges emanating if it is a single-node component. We refer to component D which contains the other end of the edge from a non-root node as the child of component C (C is the component parent of D). If a component root has children in different components, these components are referred to as the sibling components. Two immediate sibling components are each other’s left and right sibling components. As mentioned in section 2, each mini-tree keeps (long) pointers to its parent, leftmost/rightmost children and left/right sibling mini-trees. Similarly, each micro-tree keeps (short) pointers to its parent, child, and left/right sibling microtrees. These pointers can be trivially maintained under updates. Given these

pointers, the basic navigation operations named are easy to implement. For instance, given a node to find its right sibling, we first consult the look-up table and if there is no right sibling there and the node is a micro-tree root, we locate the right sibling micro-tree and consult the look-up table for that micro-tree. If there is no right sibling micro-tree and the node is a mini-tree root, we find the right sibling mini-tree and find the leftmost child therein. The edge going out of a component from a non-root node v is dealt with as an exception and data is explicitly stored to accommodate for it. Thus, we can support basic navigation queries on the succinct tree: Theorem 2. A tree with n nodes and satellite data of length b bits associated with all nodes can be represented in (2 + b)n + o (bn) bits and maintained in constant amortized time per insertions and deletions such that it facilitates navigation by supporting parent, first/last-child, previous/next-child in worstcase constant time. Furthermore, given any node, its data can be accessed and modified in worst-case constant time. ⊓ ⊔

5

Support for enhanced queries

We showed in section 4 how basic navigation on tree can be performed in constant time. Nevertheless, more enhanced operations that allow us to gallop in the tree (such as going directly to the i-th child of a node) or obtaining useful information on nodes of the tree (such as subtree size of a node) are of interest. As we will discuss in section 5.1, it is infeasible to support such enhanced queries in constant time when insertion and deletions are performed in arbitrary locations. In previous work [1, 2] on binary trees, the difficulty is felt and restrictions are put in place to support queries such as subtree size of a node in constant time. The restriction is updates are performed during a course of a traversal which starts and ends at the root, and furthermore, queries can be answered only after the traversal is completed. We strengthen the model by separating the issue of updates from queries while supporting updates in amortized constant time and queries in worst-case constant time. We allow queries to be performed anywhere in the tree while restrict updates to a crawl on the tree. 5.1

Lower bounds

In this section, we show the infeasibility of supporting enhanced operations in constant time, if dynamic updates are performed in arbitrary locations and not in form of a crawl. Our lower bounds derive from the lower bounds on the List representation and subset rank problems proved by Fredman and Saks [13]. Chan et al. [14] also derive lower bounds for dynamic succinct texts using the same set of results. The proofs are ommitted due to lack of space. Theorem 3. Maintaining an ordered tree under insertions and deletions of leaves to support navigation queries parent and child(v, k) and access satellite data requires Ω (log n/ log log n) amortized time per operation. ⊓ ⊔

Theorem 4. Maintaining an ordered tree under insertions and deletions in arbitrary locations to support sub-tree size queries requires Ω (log n/ log log n) amortized time per operation. ⊓ ⊔ 5.2

The dynamic model

As mentioned previously, we allow queries to be asked anywhere in the tree, however we require the updates not to jump from a node to a distant node and therefore only crawl on the tree. One can visualize this as if there is a finger which is initially at the root of the tree. The finger can travel from a node to its leftmost or rightmost child. Inversely, the finger can go from a child to its parent. The finger can move from a node to its immediate left/right siblings. We note that we charge for each movement of the finger and thus the update time is amortized over the movement of finger as well as the updates performed. Queries other than updates, on the other hand, can be asked anywhere on the tree and a query can be asked on a node independent of the history of the locations where previous queries have been asked. 5.3

Succinct dynamic prefix sum data structure

In support for enhanced queries, we use a data structure which indexes prefix sums in a dynamic array. The dynamic model is the finger-update model where there is a finger and only the position which is under the finger can be updated at any time and the finger moves from an element one step to the left or right at a time. The desired queries to support are ps rank and ps select queries. Pt Query ps rank(t) simply reports i=1 A[i] and ps select(s) returns index k P P such that ki=1 A[i] ≤ s < k+1 i=1 A[i]. Hon et al. [15] studied the same problem, although in the fully-dynamic model where updates perform in arbitrary independent locations, and thus operations are supported in non-constant time as there are similar lower bounds as discussed in section 5.1. We will show in the proof of theorem 5 that the finger dynamic array problem can be reduced to the case where the array is only updated from one end. This case is captured in the following lemma whose proof we omit due to lack of space. Pt Lemma 1. Let A[1..t] be a non-negative array of integers such that i=1 A[i] ≤ n for some previously known n and ∀i; A[i] < lgc n for some absolute constant c > 0. There exists a data structure which requires O (t log n) + o (n) bits and maintains the array under insertions at the end, and deletions from the end in worst-case constant time per update and it can answer ps rank and ps select queries in worst-case constant time. ⊓ ⊔ Pt Theorem 5. Let A[1..t] be a non-negative array of integers such that i=1 A[i] ≤ n for some previously known n and ∀i; A[i] < lgc n for some absolute constant c > 0. There exists a data structure which requires O (t log n) + o (n) bits and maintains the array under insertions/deletions in the finger-update model in worst-case constant time per update. This structure can answer ps rank and ps select queries in worst-case constant time.

Proof. The idea is to break the array from where the finger lies into two arrays Left and Right. These two arrays grow/shrink from the end to simulate the finger-update array. Movement of the finger to left and right corresponds to insertion of an element from one piece and its deletion from the other. A ps rank(i) query where i is to the left of the update finger can be answered by the same query in Left array. In case i lies in the Right array the answer to ps rank(n-i) in the Right array is deducted from the total sum of all elements and returned. Similarly, ps select(i) can be derived from the answer to such queries in Left or Right array depending on whether i is less than or larger than the total sum of elements in array Left. ⊓ ⊔ As we delete and insert elements the sum of elements changes. In lemma 1 and theorem 5 we assumed prior knowledge of an upper bound on the sum. However, such knowledge does not always exist in advance and the structure must be adaptive to the total sum as it changes. We allow updates which are increments and decrements by one and insertion and deletions of zeros. Under this model, we can afford to rebuild the structure as the value of the total sum doubles or halves and always stay within the desired space bound. Corollary 1. Let A[1..t] be an array of non-negative Pt integers such that ∀i; A[i] < lgc n for some absolute constant c > 0 where n = i=1 A[i]. There exists a data structure which requires O (t log n) + o (n) bits and maintains the array under decrement and increment by one and insertion and deletion of zeros in the fingerupdate model in constant amortized time per update. This structure can answer ps rank and ps select queries in worst-case constant time. ⊓ ⊔ 5.4

Implementing child(v,i) and child rank(v) operations

On a node which is not a micro-tree or a mini-tree root, the queries are answered from the look-up table. A micro/mini-tree root is dealt with using the prefix sum structure (corollary 1). For each mini/micro-tree root, we maintain an array which lists the number of children the roots has in different mini-trees (or microtrees). As children are inserted or deleted one by one and in order, the increment and decrement model of the corollary applies. Operation child(v,i) is implemented by a ps select to find the right minitree followed by a ps select to find the right micro-tree in which the a table look-up gives the answer. Similarly, operation child rank is performed by ps rank queries on the mini-tree and micro-tree and finally a table-lookup to find the rank within a micro-tree. Using corollary 1, a structure on a node v which is a mini-tree root requires O (mini-deg(v) ∗ log n)+o (deg(v)) bits where mini-deg(v) is the number of minitrees in which v has children and deg(v) is the actual degree of v. These terms sum to o (n) over the entire tree. Similarly, a structure on a node u which is micro tree root within a mini-tree requires O (micro-deg(v) ∗ log log n) + o log2 n bits where micro-deg(v) is the number of micro-trees within the mini-tre in which v has children. Over all mini-trees these terms sum to o (n) bits.

5.5

Implementation of subtree size operation

The implementation of subtree size in a static tree is that each mini-tree explicitly stores its subtree size and, within a mini-tree, each micro-tree stores its subtree size within the mini-tree [10]. To determine subtree size(v), we determine the subtree size within the containing micro-tree using the look-up table, the descendent micro-tree (if any) has the subtree size within the mini-tree stored explicitly. Finally, the descendent mini-tree (if any) has the subtree size in the entire tree explicitly stored. A dynamic implementation of subtree size resembles the static tree representation: the same information is retained at the mini-tree and micro-tree roots. However, the information is not necessarily valid at all nodes at all times. Particularly, the subtree sizes stored at mini-tree and micro-tree roots which are ancestors of the update finger node are not up-to-date. We maintain the invariant that roots which are not an ancestor of the current node, with the update finger, possess up-to-date information. This is easily maintainable by updating the sub-tree size of a root when the finger is moved up from one of its children. Thus, nodes other than those on the path from the root to the finger node can determine their subtree size as in the static case. We denote by m1 , m2 , . . . mi the mini-trees that the root-to-finger path crosses. For each such mini-tree mk , we maintain a value ai which is the net additions to the mini-tree (i.e. number of insertions minus the number of deletions). We store values ai in an array which is maintained as the ps rank structure in lemma 1 which allows constant-time prefix sum and thus quick suffix sum computation (we note that as we only need the ps rank functionality of the structure, numbers do not have to satisfy the non-negativity criteria).Within each mini-tree we repeat the same structure, for the micro-trees that the path crosses. Now given a node on the path, we determine the subtree size within the micro-tree using a table-lookup. We read the subtree size within the mini-tree from the descending micro-tree. This values is adjusted using the array structure on the micro-trees. Finally, the subtree size in the entire subtree is read from the descending mini-tree. This value is adjusted using the array structure on mini-trees.

6

Conclusion

We have studied the problem of maintaining an ordered tree under insertions and deletions of nodes where nodes have associated satellite data. We showed how insertions and deletions can be performed in constant amortized time to allow support for basic navigational queries and access to satellite data in worstcase constant time. This is an improvement over the poly-logarithmic update time [1] and a poly-log-log update time [2] presented for a more restricted trees (i.e. binary trees). It also improves a sublinear update time with poly-log-log query time on ordered trees [3]. We proved a lower bound to allow more enhanced operations such as determining the i-th child of a node or obtaining the subtree-size of a node. To allow

constant time support for these operations, we introduced the finger-update model where updates are performed where the update finger lies, and the update finger crawls on the tree. Nevertheless, queries other than updates can be asked on any node of the tree independent of where the update finger is. Extending permitted updates on trees to a more enhanced set, such as a set that also includes cutting and attaching entire subtrees or left/right rotations, remains open as a possible future work.

References 1. Munro, J.I., Raman, V., Storm, A.J.: Representing dynamic binary trees succinctly. In: SODA ’01: Proceedings of the twelfth annual ACM-SIAM symposium on Discrete algorithms. (2001) 529–536 2. Raman, R., Rao, S.S.: Succinct dynamic dictionaries and trees. In Baeten, J.C.M., Lenstra, J.K., Parrow, J., Woeginger, G.J., eds.: ICALP. Volume 2719 of Lecture Notes in Computer Science., Springer (2003) 357–368 3. Gupta, A., Hon, W.K., Shah, R., Vitter, J.S.: A framework for dynamizing succinct data structures. In: ICALP. (2007) 521–532 4. Jacobson, G.: Space-efficient static trees and graphs. 30th Annual Symposium on Foundations of Computer Science (FOCS) (1989) 549–554 5. Clark, D.R., Munro, J.I.: Efficient suffix trees on secondary storage (extended abstract). In: Proceedings of the annual ACM-SIAM symposium on Discrete algorithms. (1996) 383–391 6. Munro, J.I., Raman, V.: Succinct representation of balanced parentheses, static trees and planar graphs. In: IEEE Symposium on Foundations of Computer Science. (1997) 118–126 7. Benoit, D., Demaine, E.D., Munro, J.I., Raman, R., Raman, V., Rao, S.S.: Representing trees of higher degree. Algorithmica 43(4) (2005) 275–292 8. Geary, R.F., Raman, R., Raman, V.: Succinct ordinal trees with level-ancestor queries. ACM Transactions on Algorithms 2(4) (2006) 510–534 9. He, M., Munro, J.I., Rao, S.S.: Succinct ordinal trees based on tree covering. In: ICALP. (2007) 509–520 10. Farzan, A., Munro, J.I.: A uniform approach towards succinct representation of trees. In: SWAT (11th Scandinavian Workshop on Algorithm Theory). Lecture Notes in Computer Science, Springer (2008) 173–184 11. Storm, A.J.: Representing dynamic binary trees succinctly. Master’s thesis, School of Computer Science, University of Waterloo, Waterloo, Ontario, Canada (2000) 12. Arroyuelo, D.: An improved succinct representation for dynamic k-ary trees. In Ferragina, P., Landau, G.M., eds.: CPM. Volume 5029 of Lecture Notes in Computer Science., Springer (2008) 277–289 13. Fredman, M., Saks, M.: The cell probe complexity of dynamic data structures. In: STOC ’89: Proceedings of annual ACM symposium on Theory of computing, New York, NY, USA, ACM (1989) 345–354 14. Chan, H.L., Hon, W.K., Lam, T.W., Sadakane, K.: Compressed indexes for dynamic text collections. ACM Trans. Algorithms 3(2) (2007) 21 15. Hon, W.K., Sadakane, K., Sung, W.K.: Succinct data structures for searchable partial sums. In: ISAAC: Lecture Notes in Computer Science (vol. 2906), Springer (2003) 505516. (2003) 505–516