0% found this document useful (0 votes)
7 views

RetroactiveDataStructures

Uploaded by

santhosh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

RetroactiveDataStructures

Uploaded by

santhosh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

Retroactive Data Structures

ERIK D. DEMAINE
Massachusetts Institute of Technology

JOHN IACONO
Polytechnic University

AND
STEFAN LANGERMAN
Université Libre de Bruxelles

Abstract. We introduce a new data structuring paradigm in which operations can be performed on a
data structure not only in the present, but also in the past. In this new paradigm, called retroactive
data structures, the historical sequence of operations performed on the data structure is not fixed.
The data structure allows arbitrary insertion and deletion of operations at arbitrary times, subject only
to consistency requirements. We initiate the study of retroactive data structures by formally defining
the model and its variants. We prove that, unlike persistence, efficient retroactivity is not always
achievable. Thus, we present efficient retroactive data structures for queues, doubly ended queues,
priority queues, union-find, and decomposable search structures.
Categories and Subject Descriptors: E.1 [Data]: Data Structures; F.2.2 [Analysis of Algorithms and
Problem Complexity]: Nonnumerical Algorithms and Problems
General Terms: Algorithms, Theory, Design, Performance
Additional Key Words and Phrases: History, time travel, rollback, persistence, point location
ACM Reference Format:
Demaine, E. D., Iacono, J., and Langerman, S. 2007. Retroactive data structures. ACM Trans.
Algor. 3, 2, Article 13 (May 2007), 20 pages. DOI = 10.1145/ 1240233.1240236 http://doi.acm.
org/10.1145/1240233.1240236

A preliminary version of this article appeared in the 2004 Proceedings of the 15th Annual ACM-SIAM
Symposium on Discrete Algorithms (SODA), pp. 274–283. The work of the first and second authors
was supported in part by National Science Foundation Grants OISE-0334653 and CCF-0430849. The
third author is Chercheur Qualifié du FNRS.
Authors’ Addresses: E. D. Demaine, MIT Computer Science and Artificial Intelligence Labora-
tory, 32 Vassar Street, Cambridge, MA 02139, e-mail: [email protected]; J. Iacono, Polytechnic
University, 5 MetroTech Center, Brooklyn, NY 11201; http://john.poly.edu; S. Langerman,
Université Libre de Bruxelles, Département d’informatique, ULB CP212, Belgium, e-mail:
[email protected].
Permission to make digital or hard copies of part or all of this work for personal or classroom use is
granted without fee provided that copies are not made or distributed for profit or direct commercial
advantage and that copies show this notice on the first page or initial screen of a display along with the
full citation. Copyrights for components of this work owned by others than ACM must be honored.
Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers, to redistribute
to lists, or to use any component of this work in other works requires prior specific permission and/or
a fee. Permissions may be requested from Publications Dept., ACM, Inc., 2 Penn Plaza, Suite 701,
New York, NY 10121-0701 USA, fax +1 (212) 869-0481, or [email protected].
C 2007 ACM 1549-6325/2007/05-ART13 $5.00 DOI 10.1145/1240233.1240236 http://doi.acm.org/
10.1145/1240233.1240236

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
2 E. D. DEMAINE ET AL.

1. Introduction
Suppose that we just discovered that an operation previously performed in a database
was erroneous (e.g., from a human mistake), and we need to change the operation.
In most existing systems, the only method to support these changes is to rollback
the state of the system to before the time in question and then reexecute all of the
operations from the modifications to the present. Such processing is wasteful, inef-
ficient, and often unnecessary. In this article we introduce and develop the notion of
retroactive data structures, which are data structures that efficiently support modi-
fications to the historical sequence of operations performed on the structure. Such
modifications could take the form of retroactively inserting, deleting, or changing
one of the operations performed at a given time in the past on the data structure in
question.
After defining the model, we show that there is no general efficient transfor-
mation from nonretroactive structures into retroactive structures. We then turn
to the development of specific retroactive structures. For some classes of data
structures (commutative and invertible data structures, and data structures for de-
composable search problems), we present general transformations to make data
structures efficiently retroactive. For other data structures where the dependency
between operations is stronger, efficient retroactivity requires the development of
new techniques. In particular, we present a retroactive heap that achieves optimal
bounds.

1.1. COMPARISON TO PERSISTENCE. The idea of retroactive data structures


is related at a high level to the classic notion of persistent data structures be-
cause they both consider the notion of time, but otherwise they differ almost
entirely.
A persistent data structure maintains several versions of a data structure, and
operations can be performed on one version to produce a new version. In its
simplest form, modifications can only be made to the last structure, thus cre-
ating a linear relationship amongst the versions. In full persistence [Driscoll
et al. 1989], an operation can be performed on any past version to create a
new version, thus creating a tree structure of versions. Confluently persistent
structures [Fiat and Kaplan 2001] allow a new version to be created by merge-
like operations on multiple existing structures; thus the versions form a directed
acyclic graph. The data structuring techniques for persistence represent a sub-
stantial cost savings over the naı̈ve method of maintaining separate copies of all
versions.
The key difference between persistent and retroactive data structures is that in
persistent data structures, each version is treated as an unchangeable archive. Each
new version is dependent on the state of existing versions of the structure. However,
because existing versions are never changed, the dependence relationship between
two versions never changes. The user can view a past state of the structure, but
changes in the past state can only occur by forking off a new version from a past
state. Thus, the persistence paradigm is useful for maintaining archival versions of
a structure, but inappropriate for when changes must be made directly to the past
state of the structure.
In contrast, the retroactive model we define allows changes to be made directly to
previous versions. Because of the interdependence of versions, such a change can

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
Retroactive Data Structures 3

radically affect the contents of all later versions. In effect, we sever the relationship
between time as perceived by a data structure, and time as perceived by the user of
a data structure. Operations such as “Insert 42” now become “Insert at time 10 the
operation ‘Insert 42’ ”.

1.2. MOTIVATION. In a real-world environment, large systems processing many


transactions are commonplace. In such systems, there are many situations where
the need arises to alter the historical sequence of operations that were previously
performed on the system. We now suggest several applications where a retroactive
approach to data structures would help:
Simple Error. Data was entered incorrectly. The data should be corrected and all
secondary effects of the data removed.
Security Breaches. Suppose some operations were discovered to have been mali-
ciously performed by an unauthorized user. It is particularly important in the context
of computer security not only to remove the malicious transactions, but also to act
as if the malicious operation never occurred. For example, if the intruder modified
the password file, not only should we restore that file, but we should also undo
logins enabled by this modification.
Tainted Sources. In a situation where data enters a system from various automated
devices, if one device is found to have malfunctioned, all of its transactions are
invalid over a period of time and must be retroactively removed. For example, in
a situation where many temperature readings from various weather stations are
reported to a central computer, if one weather station’s sensors are discovered to be
intermittently malfunctioning, we wish to remove all of the sensor readings from
the malfunctioning station because they are no longer reliable. Secondary effects
of the readings, such as averages, historical highs and lows, along with weather
predictions, must be retroactively changed.
Disconnection. Continuing with the weather-station analogy of the previous para-
graph, suppose the transmission system for one weather station is damaged, but the
data is later recovered. We should then be able to retroactively enter the reports from
the weather station, and see the effects of the new data on, for example, current and
past forecasts.
Online Protocols. In a standard client-server model, the server can be seen as
holding a data structure, and clients send update or query operations. When the order
of requests is important (e.g., Internet auctions), the users can send a timestamp
along with their requests. In all fairness, the server should execute the operations
in the order they were sent. If a request is delayed by the network, it should be
retroactively executed at the appropriate time in the past.
Settlements. In some cases it is mutually agreed upon by the parties involved to
change some past transaction and all of its effects. We cite one example of such
a settlement and describe how the traditional method of handing such settlements
often fails in today’s systems. Suppose you have two charge cards from one com-
pany. When a bill comes from one card, you pay the wrong account. Upon realizing
the mistake, you call customer service and reach a settlement in which the pay-
ment is transferred into the correct account. Unfortunately, the next month, you
are charged a late fee for the late payment of the bill. You call customer service

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
4 E. D. DEMAINE ET AL.

again, and the late fee is removed as per the previous agreement. The next month,
interest from the (now removed) late fee appears on the bill. Once again you must
call customer service to fix the problem. This sequence of events is typical and
results from the system’s inability to retroactively change the destination of the
payment.
Intentional Manipulation of the Past. In Orwell’s 1984 [1949], the protagonist’s
job was to change past editions of a newspaper to enable the government to effec-
tively control the past. “A number of the Times which might, because of changes
in political alignment, or mistaken prophecies uttered by Big Brother, have been
rewritten a dozen times still stood on the files bearing its original data, and no other
copy existed to contradict it.” [Orwell 1949, p. 37]
While we may consider this to be inappropriate behavior for a government,
in many corporate settings, such behavior is commonplace. If the actions of an
executive of the corporation are bringing negative publicity to a company, it may
be desirable to not only remove the executive from the company, but to purge the
companies past and present literature of references to this person, while maintaining
consistency amongst documents.
Version Control. Software such as Microsoft Word and CVS allow maintenance
of a version tree of documents. The software allows the user to look at historical
versions and to create new versions from them. When a mistake is discovered,
it is possible to rollback the documents involved to a previous version, and start
again from this version. However, in some situations, it would be useful if we could
change a previous version and then propagate these changes into future versions. For
example, suppose that there are many versions of documentation corresponding to
the many versions of a product, and all of these versions are available online for users
of the various versions. If an error is found in the documentation, we would like to be
able to change the error in the version where it was introduced, and have the change
automatically propagate into all of the documents containing the error (though
perhaps some later versions changed the erroneous text for other reasons, and thus
need not be changed). Although such changes could be propagated by brute-force
methods, a retroactive approach would be able to quickly make such changes,
thus leading to a new generation of generalized document life-cycle management
tools.
Dynamization. Some static algorithms or data structures are constructed by per-
forming on some dynamic data structure a sequence of operations determined
by the input. For example, building the point-location data structure of Sarnak
and Tarjan [1986] consists of performing a sequence of insertions and deletions
on a persistent search tree. Specifically, the evolution of the search tree tracks
the intersection of the input with a vertical line that sweeps continuously from
left-to-right; thus, queries at a particular time in the persistent structure corre-
spond to queries at a particular horizontal coordinate. If we used full retroac-
tivity instead of persistence, we would have the ability to make changes to the
search tree at arbitrary times, which corresponds to dynamically changing the
input that defined the sequence of operations performed on the data structure.
The best data structure for dynamic planar point location uses O(log n log log n)
amortized time per query. Achieving dynamic planar point location in O(log n)
time per operation reduces to a problem in retroactive data structures, though

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
Retroactive Data Structures 5

FIG. 1. A single insertion of an operation in a retroactive heap data structure (here, retroactively
inserting “insert(0)” at time t = 0) can change the outcome of every delete-min operation and the
lifespan of every element.

this problem is, so far, unsolved.1 More generally, retroactive data structures
can help dynamize static algorithms or data structures that use dynamic data
structures.
1.3. TIME IS NOT AN ORDINARY DIMENSION. One may think that the problem
of retroactive data structures can be solved by adding one more dimension to the
structure under consideration. For example, in the case of a min-heap, it would seem
at first glance that we could create a two-dimensional variant of a heap, and the
problem would be solved. The idea is to assign the key values of items in the heap
to the y axis and use the x axis to represent time. In this representation, each item
in the heap is represented by a horizontal line segment. The left endpoint of this
segment represents the time at which an item is inserted into the heap and the right
endpoint represents when the item is removed. If the only operations supported by
the heap are insert() and delete-min(), then we have the additional property that
there are no points below the right endpoint of any segment because only minimal
items are removed from the heap. While this seems to be a clean two-dimensional
representation of a heap throughout time, retroactively adding and removing an
operation in the heap cannot simply be implemented by adding or removing a line
segment. In fact, the endpoints of all the segments could be changed by inserting a
single operation, as illustrated in Figure 1.

1
This problem is indeed our original motivation for introducing the notion of retroactive data
structures. It is probably the same motivation that led Driscoll et al. [1989] to pose their open problem:
“Find a way to allow update operations that change many versions simultaneously.” The particular
case of modifying the versions corresponding to an interval of time (posed explicitly as well) is
equivalent to retroactivity if the operations have inverses (see Section 4). A similar idea is suggested
explicitly in Snoeyink’s survey on point location [1997, p. 566], where he asks “can persistent data
structures be made dynamic?”

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
6 E. D. DEMAINE ET AL.

Thus, while time can be drawn as a spatial dimension, this dimension is special
in that complicated dependencies may exist so that when small changes are made to
some part of the diagram, changes may have to be made to the rest of the diagram.
Thus, traditional geometric and high-dimensional data structures cannot be used
directly to solve most retroactive data-structure problems. New techniques must
be introduced to create retroactive data structures, without explicitly storing every
state of the structure.
1.4. OUTLINE. The rest of the article proceeds as follows. In Section 2, we fur-
ther develop the model of retroactive data structures and explore possible variants
on the model. Next, Section 3 considers some basic problems about retroactivity,
proving separations among the model variations and proving that automatic effi-
cient retroactivity is impossible in general. In Section 4, we present two general
transformations to construct an efficient retroactive version of a data structure, one
for commutative invertible operations and one for any decomposable search prob-
lem. Finally, in Section 5, we discuss specific data structures for which we propose
to create efficient retroactive structures. Table I in Section 5 gives a partial summary
of the results obtained.

2. Definitions
In this section, we define the precise operations that we generally desire from a
retroactive data structure.
2.1. PARTIAL RETROACTIVITY. Any data structural problem can be reformu-
lated in the retroactive setting. In general, the data structure involves a sequence
of updates and queries made over time. We define the list U = [u t1 , . . . , u tm ] of
updates performed on the data structure, where u ti is the operation performed at
time ti , and t1 < t2 < · · · < tm . (We assume that there is at most one operation
performed at any given time).
The data structure is partially retroactive if, in addition to supporting updates
and queries on the “current state” of the data structure (present time), it supports
insertion and deletion of updates at past times, as well. In other words, there are
two operations of interest:
(1) Insert(t, u): Insert into U a new update operation u at time t (assuming that no
operation already exists at time t).
(2) Delete(t): Delete the past update operation u t from the sequence U of updates
(assuming such an operation exists).
Thus, the retroactive versions of standard insert(x) and delete(x) operations are
Insert(t, “insert(x)”), Insert(t, “delete(x)”), and Delete(t), where t represents a
moment in time. For example, if ti−1 < t < ti , Insert(t, “insert(x)”) creates a
new operation u = insert(x), which inserts a specified element x, and modifies
history to suppose that operation u occurred between operations u ti−1 and u ti in the
past. Informally, we are traveling back in time to a prior state of the data structure,
introducing or preventing an update at that time, and then returning to the present
time.
All such retroactive changes on the operational history of the data structure po-
tentially affect all existing operations between the time of modification and the

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
Retroactive Data Structures 7

present time. Particularly interesting is the (common) case in which local changes
propagate in effect to produce radically different perceived states of the data struc-
ture. The challenge is to realize these perceived differences extremely efficiently
by implicit representations.
2.2. FULL RETROACTIVITY. The definitions just presented capture only a partial
notion of retroactivity: the ability to insert or delete update operations in the past,
and to view the effects at the present time. Informally, we can travel back in time
to modify the past, but we cannot directly observe the past. A data structure is fully
retroactive if, in addition to allowing updates in the past, it can answer queries about
the past. In some sense, this can be seen as making a partially retroactive version of a
persistent version of the original structure. Thus, the standard search(x) operation,
which finds an element x in the data structure, becomes Query(t, “search(x)”),
which finds the element x in the state of the data structure at time t.
2.3. RUNNING TIMES. When expressing the running times of retroactive data
structures, we will use m for the total number of updates performed in the structure
(retroactive or not), r for the number of updates before which the retroactive oper-
ation is to be performed (i.e., tm−r < t ≤ tm−r +1 ), and n for the maximum number
of elements present in the structure at any single time. Most running times in this
article are expressed in terms of m, but in many cases, it is possible to improve the
data structures to express the running time of operations in terms of n and r , so that
retroactive operations performed at a time closer to the present are executed faster.
2.4. CONSISTENCY. We assume that only valid retroactive operations are per-
formed. For example, in a retroactive dictionary, a delete(k) operation for a key k
must always appear after a corresponding insert(k) in the list U ; and in a retroactive
stack, the number of push() operations is always larger than that of pop() operations
for any prefix of U . The retroactive data structures we describe in this article will
not check the validity of retroactive updates, but it is often easy to create a data
structure so as to verify the validity of a retroactive operation.

3. General Theory
The goal of this research is to design retroactive structures for abstract data types
with performance similar to their nonretroactive counterparts. This section consid-
ers some of the most general problems concerning when this is possible.
Unless stated otherwise, our data structures use the RAM model of computation
(or Real RAM when real values are used), and sometimes work in the pointer-
machine model [Tarjan 1979] as well. Our lower bounds use the history-dependent
algebraic-computation-tree model [Frandsena et al. 2001] or the cell-probe model
[Yao 1981].
3.1. AUTOMATIC RETROACTIVITY. A natural question in this area is the follow-
ing: Is there a general technique for converting any data structure in, for example,
the pointer-machine model into an efficient partially retroactive data structure?
Such a general technique would nicely complement existing methods for making
data structures persistent [Driscoll et al. 1989; Fiat and Kaplan 2001]. As described
in the Introduction, retroactivity is fundamentally different from persistence, and
known techniques do not apply.

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
8 E. D. DEMAINE ET AL.

One simple approach to this general problem is the rollback method. Here we store
as auxiliary information all changes to the data structure made by each operation
such that every change could be reversed. (For example, to enable rollback of a
memory-write operation, we store the value that was previously at the address.)
For operations in the present, the data structure proceeds as normal, modulo some
extra logging. When the user requests a retroactive change at a past time t with
tm−r < t < tm−r +1 , the data structure rollsback all changes made by operations
u m , . . . , u m−r +1 , then applies the retroactive change as if it were the present, and
finally reperformances all operations u m−r +1 , . . . , u m . Notice that these reperfor-
mances may act differently from how the operations were performed before, de-
pending on the retroactive change. Because the changes made to the data structure
are bounded by the time taken by the operations, a straightforward analysis proves
the following theorem.
THEOREM 1. Given any RAM data structure that performs a collection of oper-
ations, each in T (n) worst-case time, there is a corresponding partially retroactive
data structure that supports the same operations in O(T (n)) time, and supports
retroactive versions of those operations in O(r T (n)) time.
The rollback method is widely used in database management systems (see, e.g.,
Ramakrishnan and Gehrke [2002]) and robust file systems for concurrency control
and crash recovery. It has also been studied in the data structures literature under the
name of unlimited undo or backtracking [Mannila and Ukkonen 1986; Westbrook
and Tarjan 1989].
Of course, this result, as well as its extension to operations with nonuniform
costs, is far too inefficient for applications where r can be n or even larger—the
total number m of operations performed on the data structure. A natural goal is to
reduce the dependence on r in the running time of retroactive operations. We show
that this is not possible in the history-dependent algebraic-computation-tree model
[Frandsena et al. 2001], a generalization of the algebraic-computation-tree model in
which nodes can branch based on any finite-arity arithmetic predicate and in which
the entire tree of an operation can depend on the branches in all previous operations.
As a result, all lower bounds in this model carry over to the real-RAM model,
straight-line-program model, and algebraic-computation-tree model, as well. The
result also applies to the integer-RAM model, which allows indirect addressing
into an array by computed values, and the generalized real-RAM model, which
allows any piecewise-continuous function as an atomic operation; see Frandsena
et al. [2001].
THEOREM 2. There exists a data structure in the straight-line-program model
that supports updates and queries in O(1) time per operation, but any partially
retroactive data structure for the same operations requires (r ) time for ei-
ther updates or queries, both worst case and amortized, in the history-dependent
algebraic-computation-tree model, integer-RAM model, and generalized real-RAM
model.
PROOF. The data structure maintains two values X and Y, initially 0, and sup-
ports the updates addX(c) and addY(c), which add the value c to the value X or Y,
respectively, and mulXY(), which multiplies Y by X and stores the resulting value
in Y. Queries return the value of Y.

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
Retroactive Data Structures 9

Consider the following sequence of m = 2n + 1 operations:


[addY(an ), mulXY(), addY(an−1 ), mulXY(), . . . , mulXY(), addY(a0 )].
At the end of the sequence, X = 0 and Y = 0. We then retroactively insert
the operation “addX(x)” at the very beginning of the sequence. The value of Y
is now a0 + a1 x + a2 x 2 + · · · + an x n , which is a polynomial of degree n in x
with arbitrary coefficients. Computation of that polynomial for a given value of x
requires (n) arithmetic operations over any infinite field, even if x is restricted
to come from any infinite subset of that field (e.g., the integers). This lower bound
holds regardless of time or space spent preprocessing the ai ’s, in the worst case
in the history-dependent algebraic-computation-tree model [Frandsena et al. 2001]
(the special case of this lower bound for the straight-line-program model is known
as Motzkin’s theorem [Strassen 1990].) The same result holds in the integer-RAM
and generalized real-RAM models [Frandsena et al. 2001]. Thus, the retroactive
insertion of the addX(x) operation, followed by a query in the present, requires (n)
time. Because this retroactive modification and query can be repeated an arbitrary
number of times, and each modification-query pair has the same lower bound, the
lower bound also applies to amortized data structures.
A somewhat weaker lower bound also holds on the more powerful cell-probe
model. This lower bound also carries over to the word-RAM model with w-bit
words for any w ≥ log2 n, and to the pointer-machine model supporting arithmetic
(but not random access) on w-bit words.
THEOREM 3. There exists a data structure supporting updates and queries in
O(1) time per operation in the word-RAM model, and in O(log n) time per operation
in the pointer-machine model,√ but any partially retroactive data structure for the
same operations requires ( r/ log r ) amortized time for either updates or queries
in the cell-probe model with cells consisting of at least log2 n bits.
PROOF. The data structure maintains a vector of m = O(n) words w 1 , w 2 , . . . ,
w m , initially 0, and supports updates of the form w i ← x and w i ← w j ◦ w k , for a
specified word value x, a specified operator ◦ of either addition or multiplication,
and specified i, j, k ∈ {1, 2, . . . , m}. Queries return the value of w i for a specified
i ∈ {1, 2, . . . , m}.
Using an O(n log n)-time O(n)-space fast Fourier transform algorithm for the
discrete Fourier transform and its inverse, we can construct a sequence of O(n log n)
updates so that, if we execute the sequence when the values of the first 2n words are
currently v 1 , v 2 , . . . , v 2n , then, after the sequence execution, the values v 1 , v 2 , . . . ,
v 2n−1 of the first 2n − 1 words form the convolution  v 1 , v 2 , . . . , v 2n−1 =
v 1 , v 2 , . . . , v n ⊗ v n+1 , v n+2 , . . . , v 2n , namely, v i = j+k=i v j v k . We start with
this update sequence as the retroactive operation sequence; the resulting first 2n − 1
word values are all 0. Then we retroactively add updates of the form w i ← x to
before this operation sequence (so r = (n log n)), and make queries in the present
about values of the w i ’s. The problem then becomes dynamic convolution √ as defined
by Frandsena et al. [2001], which has a√ lower bound
√ of ( n) in the cell-probe
model. The theorem follows because ( n) = ( r/ log r ).
3.2. FROM PARTIAL TO FULL RETROACTIVITY. A natural question about the two
versions of retroactivity is whether partial retroactivity is indeed easier to support

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
10 E. D. DEMAINE ET AL.

than full retroactivity. In other words, is it easier to answer queries only about the
present? We first give a partial answer.
THEOREM 4. In the cell-probe model, there exists a data structure supporting
partially retroactive updates in O(1) time, but fully retroactive queries of the past
require (log n) time.
PROOF. The data structure is for the following problem: Maintain a set of
numbers subject to the update insert(c) which adds a number c to the set, and the
query sum() which reports the sum of all of the numbers. For this problem, the
only retroactive update operations are Insert(t, “insert(c)”) and Delete(t), whose
effects on queries about the present are to add or subtract a number to the current
aggregate. Thus, a simple data structure solves partially retroactive updates in O(1)
time per operation. In contrast, to support queries at arbitrary times, we need both
to remember the order of update operations and to support arbitrary prefix sums.
Thus, we obtain a lower bound of (log n) in the cell-probe model by a reduction
from dynamic prefix sums [Pătrascu and Demaine 2004].
On the other hand, we can show that it is always possible, at some cost, to convert
a partially retroactive data structure into a fully retroactive one.
THEOREM 5. Any partially retroactive data structure in the pointer-machine
model with constant indegree, supporting T (m)-time retroactive updates and Q(m)-
time queries about the present,
√ can be transformed into a fully retroactive √ data
structure with amortized O( m T (m))-time retroactive updates and O( m T (m)+
Q(m))-time fully retroactive queries using O(mT (m)) space.
√ √
PROOF. We define m checkpoints t1 , . . . , t√m such that at most (3/2) m

operations have occurred between consecutive checkpoints, and maintain m ver-
sions of the partially retroactive data structure D1 , . . . , D√m , where the structure
Di only contains updates that occurred before time ti . We also store the entire se-
quence of updates. When a retroactive update is performed for time t, we perform
the update on all structures Di such that ti > t. When a retroactive query is made
at time t, we find the largest i such that t ≥ ti , and perform on Di all updates
that occurred between times ti and t, storing information about these updates for
later rollback as in Theorem 1. We then perform the query on the resulting struc-
ture. Finally, we rollback the updates to restore the initial state of the structure
Di .
Because the data structures Di have constant indegree, we can use persistent data
structures [Driscoll et al. 1989] to reduce the space usage. Given a sequence of m
operations, we perform the sequence on a fully persistent version of the partially
retroactive
√ data structure, and keep a pointer
√ Di to the version obtained after the
first i m operations for i = 1, . . . , m. The retroactive updates √ branch off a
new version of the data structure for each modified Di . After m/2 retroactive
updates have been performed, we √ rebuild the entire structure in time O(mT (m)),
adding an amortized cost of O( mT (m)) per operation. This will ensure √ that the
number
√ of updates between any two checkpoints is always between m/2 and
3 m/2. The resulting data structure will have the claimed running times. The
fully persistent version of the partially retroactive data structure after a rebuild will
use at most O(mT (m)) space because it can use at most one √ unit of space for
each computational step. The data structure will perform at most m/2 retroactive

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
Retroactive Data Structures 11


updates between two rebuilds, each using at most O( m T (m)) time and extra
space, and so the space used by the fully retroactive data structure will never exceed
O(mT (m)).

4. Transformable Structures
In this section, we present some general transformations to make data structures
partially or fully retroactive for several easy classes of problems.
4.1. COMMUTATIVE OPERATIONS. To highlight the difficult case of nonlocal
effects, we define the notion of commutative operations. A set of operation types is
commutative if the state of the data structure resulting from a sequence of operations
is independent of the order of those operations.
If a data structure has a commutative set of operations, performing an operation
at any point in the past has the same effect as performing it in the present, so we
have the following lemma.
LEMMA 1. Any data structure supporting a commutative set of operations al-
lows the retroactive insertion of operations in the past (and queries in the present)
at no additional asymptotic cost.
We say that a set of operations is invertible if, for every operation u, there is
another operation u that negates the effects of operation u, that is, the sequence of
operations [u, u ] doesn’t change the state of the data structure.
LEMMA 2. Any data structure supporting a commutative and invertible set of
operations can be made partially retroactive at no additional asymptotic cost.
For example, a data structure for searchable dynamic partial sums [Raman et al.
2001] maintains an array A[1..n] of values, where sum(i) returns the sum of the first
i elements of the array, search( j) returns the smallest i such that sum(i) ≥ j, and
update(i, c) adds the value c to A[i]. The state of the data structure at the present
time is clearly independent of the order of update operations, so it is commutative.
Any operation update(i, c) is negated by the operation update(i, −c), so the updates
are also invertible, and so any data structure for searchable dynamic partial sums is
automatically partially retroactive.
An important class of commutative data structures are for searching problems.
The goal is to maintain a set S of objects under insertion and deletion operations,
so that we can efficiently answer queries Q(x, S) that ask some relation of a new
object x with the set S. Because a set S is by definition unordered, the set of
operations for a searching problem is commutative, given that the subsequence of
operations involving the same object always starts with an insertion and alternates
between insertions and deletions. As long as the retroactive updates do not violate
this consistency condition, we have the next lemma.
LEMMA 3. Any data structure for a searching problem can be made partially
retroactive at no additional asymptotic cost.
For example, not only dictionary structures, but also dynamic convex hull or
planar-width data structures, can be stated as searching problems and are thus
automatically partially retroactive. Note that these results can also be combined
with Theorem 5 to obtain fully retroactive data structures.

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
12 E. D. DEMAINE ET AL.

4.2. DECOMPOSABLE SEARCHING PROBLEMS. A searching problem maintains


a set S of objects subject to queries Q(x, S) that ask some relation of a new object
x with the set S. We already saw in Lemma 3 that data structures for searching
problems are automatically partially retroactive. A searching problem is decom-
posable if there is a binary operator computable in constant time such that
Q(x, A ∪ B) = (Q(x, A), Q(x, B)). Decomposable searching problems have
been studied extensively by Bentley and Saxe [1980]. In particular, they show how
to transform a static data structure for such a problem into an efficient dynamic one.
In this section, we show that data structures for decomposable searching problems
can also be made fully retroactive.
THEOREM 6. Any data structure for a decomposable searching problem sup-
porting insertions, deletions, and queries in time T (n) and space S(n) can be
transformed into a fully retroactive data structure with all operations taking time
O(T (m)) if T (m) = (n  ) for some  > 0, or O(T (m) log m) otherwise. The space
used is O(S(m) log m).
PROOF. Every element that was ever inserted in the data structure can be repre-
sented by a segment on the timeline between its insertion time and deletion time (or
present time if it wasn’t deleted). We maintain a segment tree [Bentley 1977], which
is a balanced binary tree where the leaves correspond to the elementary intervals
between consecutive endpoints of the segments, and internal nodes correspond to
the union of the intervals of their children. Each segment is thus represented as the
union of O(log m) intervals, each represented by one node of the tree, and each
node of the tree will contain the set of segments it represents. For each node, we
maintain that set in a data structure supporting the desired queries. Each retroactive
update affects at most O(log m) of those data structures. Given a point t on the
timeline, the set of segments containing this point can be expressed as the union of
O(log m) sets from as many nodes. For a retroactive query Query(t, x), we query
x in each of the O(log m) sets and compose the global result using the operator.
If T (m) = (n  ), then the query and update times for a retroactive operation form
a geometric progression and the total time is O(T (n)), otherwise, the total time is
O(T (m) log m).
For example, dictionaries, dynamic point location, and nearest-neighbor query
data structures solve decomposable searching problems and thus can be made fully
retroactive. Of course, in many cases, it will be possible to improve the fully retroac-
tive data structures obtained through the application of Theorem 6. For example,
any comparison-based dictionary where only exact search queries are performed
can be made fully retroactive by storing with each key the times at which it was
present in the structure. The resulting data structure will use O(m) space and all
operations can be performed in O(log m) time, a log m factor improvement in both
time and space over the straightforward application of Theorem 6.
In other cases, however, improving upon the structures obtained from Theorem 6
seems rather difficult, as, for example, with the dictionary problem allowing pre-
decessor and successor queries. Indeed, we can view it as a geometric problem in
which we maintain a set of horizontal line segments, where the y coordinate of
each line segment is the element’s key and the x extent of the line segment is the
element’s lifetime. A faster retroactive data structure would immediately result in
a faster data structure for dynamic planar point location for orthogonal regions,

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
Retroactive Data Structures 13

TABLE I. RUNNING TIMES FOR RETROACTIVE


VERSIONS OF A FEW COMMON DATA STRUCTURES
Abstract Partially Fully
Data Type Retroactive Retroactive
dictionary (exact) O(log m) O(log m)
dictionary (successor) O(log m) O(log2 m)
queue O(1) O(log m)
stack O(log m) O(log m)
deque O(log m) O(log m)
union-find O(log m) O(log
√ m)
priority queue O(log m) O( m log m)
Here, m is the number of operations.

which may also play a role in general dynamic planar point location. In fact, this
retroactive approach is hinted at as a research direction for dynamic planar point
location by Snoeyink [1997, p. 566].

5. Maintaining the Timeline


We showed in Section 3.1 that no general technique can turn every data structure into
an efficient retroactive counterpart. This suggests that in order to obtain efficient
data structures, we need to study different abstract data types separately. In this
section, we show how to construct retroactive data structures by maintaining a
structure on top of the sequence U of update operations (i.e., timeline). Table I
gives a partial summary of our results.
In the following, we assume that the sequence U is maintained in a doubly linked
list, and that when a retroactive operation is performed at time t, a pointer to the
operation following time t in U is provided (e.g., such a pointer could have been
stored during a previous operation). In the case where the pointer is not provided, it
could easily be found in O(log m) time by maintaining a binary search tree indexed
by time on top of U .
5.1. QUEUES. A queue supports two update operations enqueue(x) and
dequeue(), and two query operations: front(), which returns the next element to
be dequeued; and back(), which returns the last element enqueued. Here we de-
scribe two data structures, one partially and one fully retroactive, that thus support
the update operations Insert(t, “enqueue(x)”), Insert(t, “dequeue()”), Delete(t), as
well as queries, Query(t, “front()”), and Query(t, “back()”). The partially retroac-
tive data structure will only allow queries at the present time.
LEMMA 4. There exists a partially retroactive queue data structure with all
retroactive updates and present-time queries taking O(1) time.
PROOF. The data structure maintains the enqueue operations ordered by time
in a doubly linked list, and two pointers: B will point to the last enqueued element
in the sequence, and F to the next element to be dequeued. When an enqueue
is retroactively inserted, it is inserted into the list. Then, if it occurs before the
operation pointed to by F, we move that pointer to its predecessor. When an enqueue
is removed, we remove it from the list. Furthermore, if it occurs before the operation
pointed by F, we move that pointer to its successor. When a dequeue, retroactive or
not, is performed, we move the front pointer to its successor, and when a dequeue
is removed, we move the front pointer to its predecessor. The B pointer is only

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
14 E. D. DEMAINE ET AL.

updated when we add an enqueue operation at the end of the list. The front() and
back() operations return the items pointed by F and B, respectively.
LEMMA 5. There exists a fully retroactive queue data structure with all retroac-
tive operations taking time O(log m) and present-time operations taking O(1)
time.
PROOF. We maintain two order-statistic trees Te and Td [Cormen et al. 2001,
Sect. 14.1]. The tree Te stores the enqueue(x) operations sorted by time, and the
Td stores the dequeue() operations sorted by time. The update operations can then
be implemented directly in time O(log m), where m is the size of the operation
sequence currently stored.
The Query(t, “front()”) operation is implemented by querying Td to determine
the number d of dequeue() operations performed at or before time t. The operation
then returns the item in Te with time rank d + 1. The Query(t, “back()”) operation
uses te to determine the number e of enqueue() operations that were performed at
or before time t, and simply returns the item in Te with time rank e. Thus, both
queries can executed in time O(log m).
Using balanced search trees supporting updates in worst-case constant time
[Fleischer 1996], and by maintaining pointers into the trees to the current front
and back of the queues, updates and queries at the current time can be supported in
O(1) time.
5.2. DOUBLY ENDED QUEUES. A doubly ended queue (deque) maintains a list
of elements, and supports four update operations: pushL(x), popL() which inserts
or deletes an element at the left endpoint of the list, pushR(x), popR() which inserts
or deletes an element at the right endpoint of the list, and two query operations
left() and right() that return the leftmost or rightmost element in the list. The deque
generalizes both the queue and stack.
THEOREM 7. There exists a fully retroactive deque data structure with all
retroactive operations taking time O(log m) and present-time operations taking
O(1) time.
PROOF. In a standard implementation of a deque in an array A, we initialize
variables L = 1 and R = 0. Then a pushR(x) operation increments R and places
x in A[R], popR() decrements R, pushL(x) decrements L and places x in A[L],
and popL() increments L. The operation left() returns A[L] and operation right()
returns A[R].
In our retroactive implementation of a deque, we also maintain L and R: If we
maintain all pushR(x) and popR() operations in a linked list U R sorted by increasing
time and associate a weight of +1 to each pushR(x) operation and a weight of −1
to each popR(), then R at time t can be calculated as a weighted sum of a prefix
of the list up to time t. The same can be done for L, maintaining the list U L , and
reversing the weights.
The values of sums for all prefixes of U R can be maintained in the modified
(a, b)-tree of Fleischer [1996] with elements of the list as leaves. In every node of
the tree, we store the sum r of U R values within the subtree rooted at that node.
Thus, the sum of the r values of nodes hanging left of a path from the root to a
leaf is the sum of the prefix of U R up to that leaf. After inserting an element with
weight c in the list and in the tree, we set the r value in the leaf to c and walk along

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
Retroactive Data Structures 15

the path to the root, adding c to the r of all right siblings along the path. Deletions
are processed symmetrically.
Finally, we have to describe how to extract A[i] from the data structure, where
i = R at time t. For this, we augment each node of the tree with two values
containing the minimum and maximum prefix sum values for all the leaves in its
subtree. Note that these values can also be maintained after insertions and deletions
by adding c to them whenever c is added to the r value of the same node, and
updating them if an insertion occurs in their subtree.
To find the contents of A[i] at time t, we find the last time t ≤ t when R had
value i. This can be done by finding the last operation in U R before time t, walking
up the tree, and walking back down the rightmost subtree for which i is between
the minimum and maximum values. The same is done for U L .
5.3. UNION-FIND. A union-find data structure [Tarjan 1975] maintains an
equivalence relation on a set S of distinct elements, that is, a partition of S into
disjoint subsets (i.e., equivalence classes). The operation create(a) creates a new
element a in S, with its own equivalence class, union(a, b) merges the two sets that
contain a and b, and find(a) returns a unique representative element for the class
of a. Note that the representative might be different after each update, so the only
use of find(a) is to determine whether multiple elements are in the same class. The
union-find structure can be made fully retroactive, but to simplify the discussion,
we replace the find(a) operation by a sameset(a, b) operation which determines
whether a and b are in the same equivalence class.
THEOREM 8. There exists a fully retroactive union-sameset data structure sup-
porting all operations in O(log m) time.
PROOF. The equivalence relation can be represented by a forest where each
equivalence class corresponds to a tree in the forest. The create(a) operation con-
structs a new tree in the forest with a unique node a, sameset(a, b) determines
whether the root of the trees of a and b are the same, and union(a, b) assumes that
a and b are not in the same tree, sets b as the root of the tree that contains it, and
creates an edge between a and b. Such a forest can be maintained in O(log m) time
per operation using the link-cut trees of Sleator and Tarjan [1983], which maintain
a forest and support the creation and deletion of nodes, edges, and the changing of
the root of a tree.
In order to support retroactive operations, we modify the aforementioned struc-
ture by adding to each edge the time at which it was created. The link-cut tree
structure also allows finding the maximum edge value on a path between two
nodes. To determine whether two nodes are in the same set at time t, we just
have to verify that the maximum edge time on the path from a to b is no larger
than t.
5.4. PRIORITY QUEUES. More sophisticated than queues, stacks, and deques is
the priority queue which supports operations: insert(k) which inserts an element
with key value k, delete-min() which deletes the element with smallest key, and
the query find-min() which reports the current minimum-key element. The delete-
min() operation is particularly interesting here because of its dependence on all
operations in the past: Which element gets deleted depends on the set of elements
when the operation is executed. More precisely, it is delete-min() that makes the
set of operations noncommutative.

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
16 E. D. DEMAINE ET AL.

FIG. 2. The “L” representation of a sequence of operations. Pairs of corresponding insert(k) and
delete-min() operations are represented by upside-down “L” shapes. Dotted vertical lines represent
bridges.

Priority queues seem substantially more challenging than queues and stacks.
Figure 1 shows an example of the major nonlocal effects caused by a minor modi-
fication to the past in a priority queue. In particular, in this example, the lifetime of
all elements change because of a single Insert(t, “insert(k)”) operation. Such cas-
cading effects need to be succinctly represented in order to avoid the cost inherent
to any explicit maintenance of element lifetimes.
Without loss of generality, we assume that all key values inserted in the structure
are distinct. Let tk denote the insertion time of key k, and let dk denote its deletion
time. Let Q t be the set of elements contained in the priority queue at time t, and let
Q now be the set of elements in the queue at the present time. Let I≥t = {k | tk ≥ t}
be the set of keys inserted after time t, and let D≥t = {k ∈ / Q now | dk ≥ t} be the
set of keys deleted after time t.
In order to construct a retroactive priority queue, we need to learn more about
the structure of the problem. For this, we represent a sequence of updates by a
planar figure where the x axis represents time, and the y axis represents key values.
In this representation, each item k in the heap is represented by a horizontal line
segment. The left endpoint (tk , k) of this segment represents the time at which an
item is inserted into the heap and the right endpoint (dk , k) represents when the
item is removed. Similarly, a delete-min() operation is represented by a vertical ray
shooting from y = −∞ and stopping at the intersection with the horizontal segment
representing the element it deletes. Thus, insert(k) operations paired with their
corresponding delete-min() are together represented by upside-down “L” shapes,
and no two “L”s intersect, while elements still in the structure at the present time
(i.e., in Q now ) are represented by horizontal rays. See Figure 2.
One obvious invariant of a priority queue data structure is that the number |Q now |
of elements present in the queue is always equal to the number of inserts minus the
number of delete-min operations. Thus, when we add an operation u = “insert(k)”
at time t in the past, one element will have to be added in Q now . There are two

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
Retroactive Data Structures 17

FIG. 3. The Insert(t, “insert(k)”) operation causes a cascade of changes of deletion times, and one
insertion in Q now .

possibilities: If the element k is not deleted between time t and the present, k
can just be added to Q now . Otherwise, the element k is deleted by some operation
u = “delete-min()”, but then the element that was supposed to be deleted by u
will stay in the structure a little longer until deleted by some other delete-min()
operation, and so on. So, the insertion of operation u causes a cascade of changes,
depicted in Figure 3.
LEMMA 6. After an operation Insert(t, “insert(k)”), the element to be inserted
in Q now is
max(k, max k ).
k ∈D≥t

PROOF. As discussed earlier, the retroactive insertion will cause several ele-
ments to extend the time during which they are present in the structure. Consider
the chain of keys k < k1 < k2 < · · · < k whose life in the structure is extended.
After the retroactive update, the extended pieces of horizontal segments are from
(t, k) to (dk1 , k), from (dki , ki ) to (dki+1 , ki ) for i = 1, . . . ,  − 1, and finally from
(dk , k ) to (0, k ). They form a nondecreasing step function which, by construction,
is not properly intersected by any of the (updated) vertical rays. The key that will
be added to Q now at the end of the retroactive update is k . Suppose there is a key
k̂ larger than k in D≥t . This implies that (dk̂ , k̂) is above every segment of the step
function. But then, the vertical ray from that point intersects the step function, a
contradiction. In the particular case where k is never deleted, the step function is
just one horizontal segment and the same argument holds.
Note that removing a delete-min() operation has the same effect as reinserting
the element that was being deleted immediately after the time of the deletion. So
we have the following corollary.
COROLLARY 1. After an operation Delete(t), where the operation at time t is
“delete-min()”, the element to be inserted in Q now is
max k .
k ∈D≥t

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
18 E. D. DEMAINE ET AL.

FIG. 4. The Insert(t, “delete-min()”) operation causes a cascade of changes of deletion times, and
one deletion in Q now .
Because D≥t can change for many values of t each time an operation is performed,
it would be quite difficult to maintain explicitly. The next lemma will allow us to
avoid this task. We say that there is a bridge at time t if Q t ⊆ Q now . Bridges are
displayed as dotted vertical lines in Figure 2.
LEMMA 7. Let t be the last bridge before t. Then
max k = max k.
k ∈D≥t k ∈I≥t −Q now

PROOF. By definition of D≥t , any key k in D≥t is not in Q now . If the same k
was inserted before time t , then k ∈ Q t , but this would contradict the fact that t
is a bridge, and so k ∈ I≥t − Q now . This shows that D≥t ⊆ I≥t − Q now , and so
max k ≤ max k.
k ∈D≥t k ∈I≥t −Q now

Let k̂ = maxk ∈I≥t −Q now k , and suppose k̂ > maxk ∈D≥t k . This implies that k̂ ∈
/ D≥t ,
and so t < dk̂ < t. Because t was the last bridge before time t, dk̂ cannot be a bridge,
and so there is another key k ∈ Q dk̂ − Q now ⊆ I≥t − Q now , and k > k̂, otherwise
k would be deleted instead of k̂. But this contradicts that k̂ was maximum.
We next study the effect of adding an operation u = “delete-min()” at time t in
the past. In this case, one element will have to be removed from Q now . Again, this
operation will have a cascading effect: If it is not in Q now , the key k that will be
deleted by operation u was supposed to be deleted by the operation u at time dk ,
but as k is being deleted at time t by u, the operation u will delete the next key up,
and so on. See Figure 4.
LEMMA 8. After an operation Insert(t, “delete-min()”), the element to be re-
moved from Q now is
min k,
k∈Q t

where t is the first bridge after time t.

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
Retroactive Data Structures 19

PROOF. Consider the chain of keys k1 < k2 < · · · < k < k whose life in the
structure is shortened, with ki ∈ D≥t and k ∈ Q now . After the retroactive update, the
shortened pieces of horizontal segments are from (t, k1 ) to (dk1 , k1 ), from (dki−1 , ki )
to (dki , ki ) for i = 2, . . . , , and finally from (dk , k) to (0, k). First, it must be clear
that there is a bridge at dk because there is no key smaller than k in Q dk , and all
keys larger than k in Q dk are also in Q now because k ∈ Q now . So we just have to
show that there is no bridge t between times t and dk . For this we observe that
the shortened segments at times t ∈ [t, dk ) form a step function, and that none of
the keys ki corresponding to the steps are in Q now , but they are in Q t .
Because removing an “insert(k)” operation from time t has the same effect as
adding a “delete-min()” operation directly before the time where it is deleted (if
that happens), we also have the next corollary.
COROLLARY 2. After an operation Delete(t) where the operation at time t is
u t = “insert(k)”, the element to be removed from Q now is k if k ∈ Q now ; otherwise,
it is
min k ,
k ∈Q t

where t is the first bridge after time t.


Again, because we do not explicitly maintain Q t for all t, we ease the computation
by using that, if t is a bridge, then Q t = I≤t ∩ Q now .
THEOREM 3. There exists a partially retroactive priority queue data struc-
ture supporting retroactive updates in O(log m) time and supporting present-time
queries in O(1) time.
PROOF. The data structure maintains the history of all update operations in a
doubly linked list, and explicitly maintains the set Q now in a binary search tree,
associating with each key a pointer to its insert operation in the linked list. After
each retroactive update, an element will be inserted or deleted in Q now according
to the rules described in the preceding lemmas. In order to decide which element
to insert or delete, we need to be able to perform two types of operations:
(A) Find the last bridge before t or the first bridge after t; and
(B) find the maximum key in I≥t − Q now or the minimum key in I≤t ∩ Q now .
If we maintain the list of updates, assigning a weight of 0 to insert(k) operations
with k ∈ Q now , +1 to insert(k) with k ∈/ Q now , and −1 to delete-min() operations,
every bridge corresponds to a prefix with sum 0. So, using the data structure used
in Theorem 7, we can answer queries of type A in O(log m) time. Because every
retroactive update adds or deletes at most one element from Q now , only one weight
change has to be performed in the structure, which also takes O(log m) time.
If we maintain the list of insertions augmented by the modified (a, b)-tree of
Fleischer [1996], and store in each internal node the maximum of all keys in its
subtree which are absent in Q now , we can easily find the maximum key in I≥t − Q now
in O(log m) time by walking down the tree. The minimum key in I≤t ∩ Q now can
also be maintained if we store in every internal node of the tree the minimum
of all keys in its subtree which are in Q now . Those values can be maintained in

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.
20 E. D. DEMAINE ET AL.

O(log m) time per retroactive update because each update changes at most one
element of Q now .
ACKNOWLEDGMENTS. We thank Michael Bender, Prosenjit Bose, Jean Cardinal,
Alejandro López-Ortiz, Ian Munro, and the anonymous referees for helpful discus-
sions and comments.

REFERENCES
BENTLEY, J. 1977. Algorithms for Klee’s rectangle problems. unpublished manuscript, Department of
Computer Science, Carnegie-Mellon University.
BENTLEY, J. L., AND SAXE, J. B. 1980. Decomposable searching problems I: Static-to-Dynamic trans-
formations. J. Alg. 1, 301–358.
CORMEN, T. H., LEISERSON, C. E., RIVEST, R. L., AND STEIN, C. 2001. Introduction to Algorithms, 2nd
ed. MIT Press, Cambridge, MA.
DRISCOLL, J. R., SARNAK, N., SLEATOR, D. D., AND TARJAN, R. E. 1989. Making data structures persis-
tent. J. Comput. Syst. Sci. 38, 1, 86–124.
FIAT, A. AND KAPLAN, H. 2001. Making data structures confluently persistent. In Proceedings of the
12th Annual Symposium on Discrete Algorithms (Washington, DC) 537–546.
FLEISCHER, R. 1996. A simple balanced search tree with O(1) worst-case update time. Int. J. Found.
Comput. Sci. 7, 2, 137–149.
FRANDSENA, G. S., HANSENB, J. P., AND MILTERSEN, P. B. 2001. Lower bounds for dynamic algebraic
problems. Inf. Comput. 171, 2 (Dec.), 333–349.
GOODRICH, M. AND TAMASSIA, R. 1991. Dynamic trees and dynamic point location. In Proceedings of
the 23rd Annual ACM Symposium on Theory Computing. 523–533.
MANNILA, H. AND UKKONEN, E. 1986. The set union problem with backtracking. In Proceedings of the
13th International Conference on Automata, Languages and Programming (ICALP). Lecture Notes in
Computer Science, vol. 226. Springer Verlag, Berlin. 236–243.
ORWELL, G. 1949. 1984. Signet Classic.
PĂTRASCU, M. AND DEMAINE, E. D. 2004. Tight bounds for the partial-sums problem. In Proceedings
of the 15th Annual ACM-SIAM Symposium on Discrete Algorithms. (New Orleans, LA). 20–29.
RAMAKRISHNAN, R. AND GEHRKE, J. 2002. Database Management Systems. McGraw-Hill, New York.
RAMAN, R., RAMAN, V., AND RAO, S. S. 2001. Succinct dynamic data structures. In Proceedings of
the 7th Workshop on Algorithms and Data Structures. Lecture Notes in Computer Science, vol. 2125.
Springer Verlag, Berlin. 426–437.
SARNAK, N. AND TARJAN, R. E. 1986. Planar point location using persistent search trees. Commun.
ACM 29, 7 (Jul.), 669–679.
SLEATOR, D. D. AND TARJAN, R. E. 1983. A data structure for dynamic trees. J. Comput. Syst. Sci. 26, 3,
362–381.
SNOEYINK, J. 1997. Point location. In Handbook of Discrete and Computational Geometry, J. E. Good-
man and J. O’Rourke, eds. CRC Press, Boca Raton, FL. 559–574.
STRASSEN, V. 1990. Algebraic complexity theory. In Algorithms and Complexity, J. van Leeuwen, ed.
Handbook of Theoretical Computer Science, vol. A. MIT Press, Cambridge, MA. 633–672.
TARJAN, R. E. 1975. Efficiency of a good but not linear set union algorithm. J. ACM 22, 215–225.
TARJAN, R. E. 1979. A class of algorithms which require nonlinear time to maintain disjoint sets. J.
Comput. Syst. Sci. 18, 110–127.
WESTBROOK, J. AND TARJAN, R. E. 1989. Amortized analysis of algorithms for set union with back-
tracking. SIAM J. Comput. 18, 1–11.
YAO, A. C. 1981. Should tables be sorted? J. ACM 28, 3, 615–628.

RECEIVED DECEMBER 2004; REVISED NOVEMBER 2006; ACCEPTED DECEMBER 2006

ACM Transactions on Algorithms, Vol. 3, No. 2, Article 13, Publication date: May 2007.

You might also like