We present our interpretation of Chan’s technique for dynamically maintaining the lower envelope of a set H of non-vertical planes in \({{\mathbb {R}}}^3\) under insertions and deletions. In the next section, we will combine this structure with the results from the previous sections to obtain a data structure that supports polylogarithmic update and query time for maintaining the lower envelope of general surfaces. As before, maintaining the lower envelope means that we can efficiently answer point location queries, each specifying a point \(q\in {{\mathbb {R}}}^2\) and asking for the lowest plane above q.
Our exposition proceeds in three steps: We begin with a static structure, then develop a simple variant (with a not so simple analysis) of a standard technique for handling insertions, and finally describe how to perform deletions. With the help of a simple charging argument in the analysis of the static structure, we also improve Chan’s original (amortized) deletion time by a logarithmic factor, from \(O(\log ^6n)\) to \(O(\log ^5n)\), the first improvement in more than ten years. Subsequently to this work, Chan found an additional improvement, resulting in amortized deletion time \(O(\log ^4 n)\) and amortized insertion time \(O(\log ^2n)\) [14]. This further improvement is based on the improvement presented in this section, combined with an improved algorithm for the data structure used in the static case.
A Static Structure
Let H be a fixed set of n non-vertical planes in \({{\mathbb {R}}}^3\). We fix a constant \(k_0 \ge 1\), and define the sequence \(k_j = 2^jk_0\), for \(j=0,1,\dots ,m\), where \(m = \lfloor \log (n/k_0)\rfloor \). We have \(k_m \in (n/2, n]\).
Next, we construct a sequence \(\{\Lambda _j\}_{j\ge 1}\) of vertical shallow cuttings, for \(j = m + 1, \dots , 0\), as follows: the shallow cutting \(\Lambda _{m+1}\) consists of a single prism \(\tau \) that covers all of \({{\mathbb {R}}}^3\) and has conflict list \({{\,\mathrm{CL}\,}}(\tau ) = H\) (the shallowness is vacuously satisfied here). Next, we set \(H_m = H\) and \(n_m = n\), and we start with \(j = m\). In round j, we have a set \(H_j \subseteq H\) of \(n_j \le n\)surviving planes, and we construct a vertical \(k_j\)-shallow \((\alpha k_j/n_j)\)-cutting \(\Lambda _j\) for \({{\mathcal {A}}}(H_j)\), for a suitable constant \(\alpha > 1\) (the same constant for all rounds; see Sect. 3, and also [16, 29]). The reason for using this hierarchy of cuttings will become clear when we discuss deletions, in Sect. 7.3. That is, \(\Lambda _j\) consists of \(O(n_j/k_j)\) semi-unbounded vertical prisms whose ceilings form the faces of a polyhedral terrain \({\overline{\Lambda }}_j\). The terrain \({\overline{\Lambda }}_j\) lies fully above level \(k_j\), and the conflict list \({{\,\mathrm{CL}\,}}(\tau )\) of each prism \(\tau \in \Lambda _j\), consisting of the planes from \(H_j\) that cross \(\tau \), is of size at most \(\alpha k_j\). After constructing \(\Lambda _j\), we identify the set \(H^\times \subseteq H_j\) of planes that belong to more than \(c\log n\) conflict lists in all cuttings \(\Lambda _m, \dots , \Lambda _j\) constructed so far;Footnote 17 here c is some sufficiently large constant that we will specify later. We remove the planes in \(H^\times \) from the conflict lists of \(\Lambda _j\) (but not from those of the higher levels \(\Lambda _{j'}\), for \(j'>j\)), and we set \(H_{j-1} = H_j {\setminus } H^\times \) and \(n_{j-1} = |H_{j-1}|\) for the next round. This pruning mechanism ensures that each plane of H appears in at most \(c\log n\) (pruned) conflict lists, within the current hierarchy of cuttings, which is crucial for the efficiency of the dynamic algorithm, to be presented in the next two subsections. Note that \({\overline{\Lambda }}_{j-1}\) is not necessarily “lower” than \({\overline{\Lambda }}_j\), since the former cutting is constructed with respect to a potentially smaller set of planes (and can therefore contain points that lie above \({\overline{\Lambda }}_j\), even though it approximates a lower-indexed level). We stop after performing the pruning step for \(\Lambda _0\). The conflict lists of \(\Lambda _0\) will be used for answering queries. (To support deletions, we will also need the conflict lists of \(\Lambda _j\), for \(j \ge 1\); see below.) We denote by \({{\mathcal {D}}}^{(1)}\) the structure consisting of the shallow cuttings \(\Lambda _{m+1},\Lambda _m, \dots , \Lambda _0\) and the pruned conflict lists of their prisms. We write \(S({{\mathcal {D}}}^{(1)})\) for the set of surviving planes in \({{\mathcal {D}}}^{(1)}\) (those that were not pruned at any stage), and \(C({{\mathcal {D}}}^{(1)}) = H\) for the initial set of planes. We say that \(S({{\mathcal {D}}}^{(1)})\) is stored in \({{\mathcal {D}}}^{(1)}\) and that \(C({{\mathcal {D}}}^{(1)})\) was used to construct \({{\mathcal {D}}}^{(1)}\). The planes in \(C({{\mathcal {D}}}^{(1)}){\setminus } S({{\mathcal {D}}}^{(1)})\) are the pruned planes in \({{\mathcal {D}}}^{(1)}\). We emphasize again that in general a pruned plane still shows up in some conflict lists of some of the cuttings \(\Lambda _j\) (for indices j higher than the one at which it was pruned). The difference is that the stored planes are kept only in \({{\mathcal {D}}}^{(1)}\), whereas the pruned planes are also passed to subsequent substructures, as we will soon describe. The following lemma bounds the size of \(S({{\mathcal {D}}}^{(1)})\).
Lemma 7.1
For any \(\zeta \in (0,1)\) there exists a sufficiently large (but constant) choice of c (the coefficient in the threshold \(c\log n\), beyond which we prune planes), such that \(|S({{\mathcal {D}}}^{(1)})| \ge (1-\zeta )\,n\).
Proof
Define the potential \(\Phi (j)\) as the total “stored size” of the conflict lists of \(\Lambda _m, \dots , \Lambda _j\), after the pruning step in round j, and set \(\Phi (m+1) = 0\). By the stored size of a conflict list \({{\,\mathrm{CL}\,}}(\tau )\), of some prism \(\tau \) of some cutting, we mean the number of planes in \({{\,\mathrm{CL}\,}}(\tau )\) that have not been pruned yet, at any of the steps \(m,m-1,\dots ,j\).Footnote 18 Since \(\Lambda _j\) has \(O(n_j/k_j)\) prisms, and each conflict list of \(\Lambda _j\) has \(O(k_j)\) planes, the overall size of the conflict lists of \(\Lambda _j\) is \(O(n_j)=O(n)\). Hence, in round j, we increase \(\Phi \) by at most \(\gamma n\), for some fixed \(\gamma > 0\), where the increase is caused by the conflict lists of the prisms of the new cutting. If a plane h is pruned at this stage, then h lies in at least \(c\log n\) conflict lists of all stages processed so far (including those at the present stage), and has to be removed from the stored size count of these prisms, so this decreases \(\Phi \) by at least \(c\log n\). Since \(\Phi \) is initially 0 and is never negative, and since we increase it by at most \(\gamma n\log n\) units throughout the construction, it follows that we prune at most \(\zeta n\) planes, if we choose \(c \ge \gamma /\zeta \). \(\square \)
We fix the fraction \(\zeta = 1/32\), and use the corresponding coefficient c in the construction. We set \(H^{(1)} = H\) and \(H^{(2)} = C({{\mathcal {D}}}^{(1)}){\setminus } S({{\mathcal {D}}}^{(1)}) = H{\setminus } S({{\mathcal {D}}}^{(1)})\) (that is, \(H^{(2)}\) consists of the planes that we have pruned). As just argued, we have \(|H^{(2)}| \le \zeta n\). We repeat the process with the set \(H^{(2)}\), obtaining an analogous structure \({{\mathcal {D}}}^{(2)}\) and a remainder set \(H^{(3)}=C({{\mathcal {D}}}^{(2)}){\setminus } S({{\mathcal {D}}}^{(2)})=H^{(2)}{\setminus } S({{\mathcal {D}}}^{(2)})\) of at most \(\zeta ^2 n\) planes that were pruned in \({{\mathcal {D}}}^{(2)}\). Proceeding in this manner, for \(s\le \log _{1/\zeta } n = (1/5)\log n\) steps, we obtain the complete target (static) structure \({{\mathcal {D}}}= ({{\mathcal {D}}}^{(1)},{{\mathcal {D}}}^{(2)},\dots ,{{\mathcal {D}}}^{(s)})\), where \({{\mathcal {D}}}^{(s)}\) involves only a constant number of planes. Thus, in the last step, the overall size of the conflict lists is (much) smaller than \(c\log n\), so all of these planes are stored, and the process can ‘safely’ terminate. By construction, the sets \(S({{\mathcal {D}}}^{(i)})\) are pairwise disjoint and their union is H. For each i, let \(m_i = \lfloor \log (|H^{(i)}|/k_0)\rfloor = O(\log n)\) be the number of cuttings in \({{\mathcal {D}}}^{(i)}\). The overall size of \({{\mathcal {D}}}^{(i)}\), including the conflict lists, is
$$\begin{aligned} O\left( \sum _{j=0}^{m_i} \frac{|H^{(i)}|}{k_j}\cdot k_j \right) =O( |H^{(i)}|\,m_i) =O( |H^{(i)}|\log n ). \end{aligned}$$
Since by Lemma 7.1, we have \(|H^{(i)}|\le \zeta ^{i-1}n\), the overall size of \({{\mathcal {D}}}\) is \(O(n\log n)\).Footnote 19 Using the algorithm of Chan and Tsakalidis [16], we construct each cutting \(\Lambda _j\), including its associated conflict lists, in any \({{\mathcal {D}}}^{(i)}\), in \(O(|H^{(i)}|\log n)\) time. Summing over j, we can construct \({{\mathcal {D}}}^{(i)}\) in \(O(|H^{(i)}|\log ^2n)\) time, and summing over i, recalling that \(|H^{(i)}|\) decreases geometrically with i, we get a total running time \(O(n\log ^2n)\).Footnote 20 We write this bound as \(an\log ^2n\), for a suitable concrete coefficient a.
Answering a query is easy: Given \(q \in {{\mathbb {R}}}^2\), we iterate over all \(O(\log n)\) substructures \({{\mathcal {D}}}^{(i)}\), and we find the prism \(\tau \) of the cutting \(\Lambda _0\) in \({{\mathcal {D}}}^{(i)}\) whose xy-projection contains q (or possibly O(1) prisms, if the query q is not in general position and falls on the boundary of several such prisms). This takes \(O(\log n)\) time, with a suitable point-location structure for the xy-projection of \({\overline{\Lambda }}_0\). We then search the conflict list \({{\,\mathrm{CL}\,}}(\tau )\) of \(\tau \), in brute force, for the lowest plane over q (or possibly planes, in case when q is not in general position). This requires \(O(k_0) = O(1)\) time. We return the plane (or planes) lowest over q among all \(O(\log n)\) candidates. The query time is thus \(O(\log ^2n)\). The correctness of this procedure is obvious, and follows from the property that the ceilings of the prisms in \(\Lambda _0\) (for any \({{\mathcal {D}}}_i\)) pass above level \(k_0\ge 1\) of \({{\mathcal {A}}}(H^{(i)})\), so the lowest plane of \(H^{(i)}\) over q belongs to the conflict list of the corresponding prism.
Handling Insertions
Here, we explain how to maintain the lower envelope of a set H of non-vertical planes in \({{\mathbb {R}}}^3\) under insertions, where the notion of maintenance is as defined in the preceding section. For simplicity, at each point in time, we denote the current number of planes in the data structure by n. Furthermore, we use N to denote the power of 2 satisfying \(n \in [N, 2N)\). Whenever n becomes too large, we double the value of N. Our structure uses a variant of a standard technique, introduced by Bentley and Saxe [7] and later refined in Overmars and van Leeuwen [44] (see also Erickson’s notes [26]). Specifically, we maintain a sequence \({{\mathcal {I}}}= ({{\mathcal {B}}}_{i_0},{{\mathcal {B}}}_{i_1},\dots ,{{\mathcal {B}}}_{i_k})\) of structures, where \(0\le i_0< i_1< \ldots < i_k \). The indices \(i_j\) are not fixed, are not necessarily contiguous, and may change after each insertion. Informally, we have an infinite sequence of bins, indexed by \(0,1,2,\dots \), and \(i_j\) is the index of the bin that stores \({{\mathcal {B}}}_{i_j}\), for \(j=0,1,\dots ,k\). We refer to \({{\mathcal {B}}}_{i}\) as the structure at location (or bin) i. Lemma 7.2 below shows that \(i_k\), and thus also k, are \(O(\log n)\). Each \({{\mathcal {B}}}_{i_j}\) is a substructure \({{\mathcal {D}}}^{(u)}\) of some static structure \({{\mathcal {D}}}\), as in Sect. 7.1, constructed over some subset of H. We maintain the following invariants.
-
(I1)
For each occupied index i, we have \(2^{i-1} < |S({{\mathcal {B}}}_{i})|\le 2^{i}\).
-
(I2)
The sets \(S({{\mathcal {B}}}_{i})\), over the occupied indices i, are pairwise disjoint, and their union is H.
For each plane \(h \in H\), we say that h is stored at location i if \(h\in S({{\mathcal {B}}}_{i})\).
Inserting a plane To insert a plane h, we determine the smallest index of an empty bin, i.e., the smallest integer \(j \ge 0\) that is not in the sequence \((i_0, i_1, \dots , i_k)\). If \(j = 0\), we store h in a trivial structure \({{\mathcal {B}}}_0\) of size 1. Otherwise, we have \((i_0, \dots , i_{j-1}) = (0,\dots , j-1)\), and we set \({H}_j := \{h\}\cup \bigcup _{i=0}^{j-1} S({{\mathcal {B}}}_{i}) \). Assuming inductively that invariants (I1) and (I2) hold prior to the insertion of h, we have
$$\begin{aligned} |{H}_j|&= 1 + \sum _{i=0}^{j-1} |S({{\mathcal {B}}}_{i})|> 1 + \sum _{i=0}^{j-1}2^{i-1} > 2^{j-1}\qquad \text {and} \end{aligned}$$
(11)
$$\begin{aligned} |{H}_j|&=1 + \sum _{i=0}^{j-1}|S({{\mathcal {B}}}_{i})| \le 1+\sum _{i=0}^{j-1}2^{i} = 2^j. \end{aligned}$$
(12)
We construct over \({H}_j\) a static structure \({{\mathcal {D}}}\), as in Sect. 7.1. Recall that \({{\mathcal {D}}}\) is a sequence of a logarithmic number of substructures, \({{\mathcal {D}}}^{(1)},{{\mathcal {D}}}^{(2)},\dots ,{{\mathcal {D}}}^{(s)}\), where (recall Lemma 7.1)
$$\begin{aligned} s \le \log _{1/\zeta }|{H}_j| = \frac{\log {|{H}_j|}}{\log (1/\zeta )}\le \frac{j}{\log (1/\zeta )} = \frac{j}{5} < j , \end{aligned}$$
by (12) and our choice of \(\zeta = 1/32\). We remove the current structures \({{\mathcal {B}}}_{0},\dots , {{\mathcal {B}}}_{j-1}\) from \({{\mathcal {I}}}\). Then, for each substructure \({{\mathcal {D}}}^{(u)}\) constructed for \({H}_j\), for \(u=1,\dots ,s\), we set \({{\mathcal {B}}}_{i_u} := {{\mathcal {D}}}^{(u)}\) for \(i_u = \lceil {\log {|S({{\mathcal {D}}}^{(u)})|}}\rceil \), and add \({{\mathcal {B}}}_{i_u}\) to \({{\mathcal {I}}}\).
We have \(C({{\mathcal {D}}}^{(1)}) = H_j\). By Lemma 7.1 and (11), \(|S({{\mathcal {D}}}^{(1)})| \ge (1-\zeta ) |H_j| \ge (1-\zeta )\, 2^{j-1} > 2^{j-2}\) (recall that \(\zeta = 1/32\)), so it follows that \({{\mathcal {D}}}^{(1)}\) is placed in bin j or \(j-1\). Moreover, by Lemma 7.1, we have \(|S({{\mathcal {D}}}^{(u+1)})| \le \zeta \,|C({{\mathcal {D}}}^{(u)})| \le \zeta \,|S({{\mathcal {D}}}^{(u)})|/({1-\zeta })\), so the corresponding indices satisfy
$$\begin{aligned} i_{u+1}&= \lceil \log {|S({{\mathcal {D}}}^{(u+1)})|} \rceil \le 1 + \log {|S({{\mathcal {D}}}^{(u+1)})|} \\&\le 1 + \log {\frac{\zeta \,|S({{\mathcal {D}}}^{(u)})|}{1-\zeta }}= 1 + \log {|S({{\mathcal {D}}}^{(u)})| }- \log 31 \\&= \log {|S({{\mathcal {D}}}^{(u)})|} - \log 15.5 \le \lceil \log { |S({{\mathcal {D}}}^{(u)})|}\rceil - \log 15.5 = i_u - \log 15.5 , \end{aligned}$$
since \(\zeta = 1/32\). That is, since both \(i_u\) and \(i_{u+1}\) are integers, \(i_{u+1} \le i_u - 4\). Hence, each structure \({{\mathcal {D}}}^{(u)}\) is assigned a different index \(i \le j\) (with a gap of at least three empty bins between consecutive occupied ones) and invariants (I1) and (I2) hold by construction ((I1) follows from the definition of the indices \(i_u\)).
Answering a query To answer a query q, we find in each substructure \({{\mathcal {B}}}_{i}\) of \({{\mathcal {I}}}\) the prism (or prisms, in case of a non-generic query) of the corresponding lowest-index cutting \(\Lambda _0\) whose xy-projection contains the query point q, and we search over the at most \(k_0\) planes of its conflict list for the lowest ones over q. We output the lowest among all these planes, over all substructures. This takes \(O(\log n)\) time per structure, as in the static case.
The correctness of this procedure follows from invariant (I2). Indeed, if h is a lowest plane over a query point q, then \(h \in S({{\mathcal {D}}}^{(i)})\) for some unique i (by invariant (I2)). Since h is stored at \({{\mathcal {D}}}^{(i)}\), it has not been pruned from any conflict list of this substructure. Let \(\tau \) be a prism of the lowest-indexed cutting \(\Lambda _0\) of \({{\mathcal {D}}}^{(i)}\) whose xy-projection contains q. By construction, the ceiling of \(\tau \) lies above the \(k_0\)-level of the corresponding arrangement, which implies that h must lie in \(\tau \) over q. This, and the fact that h has not been pruned, implies that h belongs to the (pruned) conflict list \({{\,\mathrm{CL}\,}}(\tau )\), so the query will encounter h, and thus will output it as the correct answer. The following lemma bounds the size of \({{\mathcal {I}}}\).
Lemma 7.2
The largest index of an occupied bin is at most \(\log N + 1\), and thus the number of structures in \({{\mathcal {I}}}\) is at most \(\log N + 2\).
Proof
By definition, the number of planes in the structure satisfies \(n < 2N\) and, by invariant (I1), the largest index \(i\in {{\mathcal {I}}}\) satisfies
$$\begin{aligned} 2^{i-1}< |S({{\mathcal {B}}}_i)| \le n< 2N\quad \ \text {or}\ \quad i < 1+ \log (2N) = \log N + 2 , \end{aligned}$$
that is \(i \le \log N + 1\) (since \(\log N\) is an integer). \(\square \)
Running time We now bound the running time of our insertion-only structure. In particular, we are going to show that the deterministic amortized cost of an insertion is \(O(\log ^3n)\) and the deterministic worst-case cost of a query is still \(O(\log ^2n)\), as in the static case.
Indeed, the bound on the query time is immediate by Lemma 7.2 and the observation preceding it, because \(\log N = O(\log n)\). To analyze the amortized insertion cost, we use a charging argument. Each plane h that is currently stored in \({{\mathcal {I}}}\) holds \(b(w-i)\)credits, each worth \(a\log ^2 N\)units, where i is the current unique location (bin index) of the structure \({{\mathcal {B}}}_i\) for which \(h\in S({{\mathcal {B}}}_i)\), and \(w:= \log N + 2\) bounds, by Lemma 7.2, the maximum length of \({{\mathcal {I}}}\). Here a is the coefficient of the bound \(an\log ^2n\) for the construction time of the static structure on n planes (see Sect. 7.1), and b is some absolute constant to be fixed shortly. Note that the number of credits held by a plane h is larger when the bin index where h is stored is smaller.
We define the potential \(\Psi \) of the structure as the overall number of units of credit that its planes hold. The amortized cost of an insertion is defined to be bw credits, that is, \(abw\log ^2N\) units. When a new plane is inserted, we give it bw credits, that is, \(abw\log ^2N\) units of credit. The unit size depends on N, so the whole charging scheme has to be updated every time N is doubled. Specifically, when N is doubled, the increase in the size of a credit is
$$\begin{aligned} a\log ^2(2N) - a\log ^2N = a\,(1+\log N)^2 - a\log ^2N = a\,(1+2\log N). \end{aligned}$$
We have 2N planes in the structure at this moment, and each of them carries at most bw credits. Hence, updating the overall amount of credit in the structure in this doubling costs \(O(Nw\log N)\) units, which is \(O(N\log ^2N)\). There are only \(O(\log n)\) doubling steps, and the N’s that they involve are powers of 2, implying that the overall additional cost of updating the credit distribution during doublings of N is \(O(n\log ^2n)\). In what follows we ignore this issue of updating the credit size, whose cost will be subsumed by the overall cost of the insertions, and just use the number of credits in our charging scheme.Footnote 21
We recall that, when inserting a new plane h, we destroy a prefix of j substructures in \({{\mathcal {I}}}\), put all their planes, including h, in a subset \({H}_{j}\), compute a new static structure \({{\mathcal {D}}}\) for \({H}_j\), and spread its substructures \({{\mathcal {D}}}^{(u)}\) into some subset of bins with indices from j downwards. Set \(t = |{H}_{j}|\). As noted above, by the analysis in Sect. 7.1, the real cost of the insertion is at most \(at\log ^2 t\), or, in other words, at most t credits. The main claim in the complexity analysis of insertions is the following lemma.
Lemma 7.3
With the above notations, for a sufficiently large choice of the constant b, we have
$$\begin{aligned} at\log ^2 t + \Delta \Psi \le abw\log ^2N , \end{aligned}$$
(13)
where \(\Delta \Psi = \Psi ^+ - \Psi ^-\), where \(\Psi ^+\) and \(\Psi ^-\) are, respectively, the values of the potential just after and just before the insertion.
Proof
Consider the sequence \({{\mathcal {D}}}^{(1)},{{\mathcal {D}}}^{(2)},\dots ,{{\mathcal {D}}}^{(s)}\) of substructures that we construct over \({H}_j\), where \(s=\lfloor \log _{1/\zeta } |{H}_j|\rfloor \). Recall that by (11) and (12), we have that \(2^{j-1} < t=|{H}_{j}| \le 2^j\). In particular, \(s\le ({1}/{5}) \log t \le j/5 < j\). As already noted, by Lemma 7.1, \(|S({{\mathcal {D}}}^{(1)})| \ge (1-\zeta )\,t\ge (1-\zeta )\,2^{j-1}\), and consequently (since \(\zeta = 1/32\)), the structure \({{\mathcal {D}}}^{(1)}\) is placed either in bin j or bin \(j-1\). Furthermore, the lower bound in invariant (I1) shows that before the insertion, at least \(\sum _{i=1}^{j-2}2^{i-1} + 1> 2^{j-2}\ge t/4\) planes of \({H}_j\) were stored at bins \(i=0, 1, \dots , j - 2\) (the \( + 1\) is for bin 0, which contains exactly one plane). Since \(|S({{\mathcal {D}}}^{(1)})|\ge (1-\zeta )\,t\), it follows that at least \(t/4 -\zeta t\) among the planes that were stored in bins \(i=0,1,\dots , j-2\), end up at \({{\mathcal {B}}}_j\) or \({{\mathcal {B}}}_{j-1}\) following the insertion. These planes release at least \(bt\,(1/4 -\zeta )\) credits, that is, they decrease \(\Psi \) by at least these many credits.
The technical issue that we need to address is that some planes in \({{\mathcal {D}}}^{(2)},\dots ,{{\mathcal {D}}}^{(s)}\) may require more credits than what they had before the insertion, if they end up in smaller-indexed bins than the bins in which they were stored before the insertion. We claim that the overall amount of this extra credit is much smaller than the amount of released credit, so the released credit (more than) suffices to fill in the required extra credit, thereby making each plane hold the correct amount of credit, with change to spare. That is, the insertion does cause \(\Psi \) to decrease.
To show this, let \((j-1)-j_i\) be the bin index in which we put \({{\mathcal {D}}}^{(i)}\), for \(2\le i \le s\). In the worst case, each plane of \({{\mathcal {D}}}^{(i)}\) was stored in bin \(j-1\) before the insertion and now requires \(b j_i\) additional credits. (Note that h does not participate in this argument: it cannot release any credit since it did not exist before the insertion; nevertheless, the credits that it gets as it is being inserted more than suffice for any bin h is eventually placed in.) Summing up, we get that the number of additional credits that we need to give the planes is at most \(b\sum _{i=2}^s j_i | S({{\mathcal {D}}}^{(i)})|\). From the definition of the insertion mechanism, we get that \((j-1)-j_i = \lceil {\log {|S({{\mathcal {D}}}^{(i)})|}}\rceil \), so the total number of additional credits that we need to give these planes is at most
$$\begin{aligned} \begin{aligned} b\sum _{i=2}^s j_i |S({{\mathcal {D}}}^{(i)})|&=b \sum _{i=2}^s \bigl (j-1-\lceil \log |S({{\mathcal {D}}}^{(i)})|\rceil \bigr )|S({{\mathcal {D}}}^{(i)})| \\&\le b \sum _{i=2}^s \bigl (j-1-\log |S({{\mathcal {D}}}^{(i)})|\bigr )|S({{\mathcal {D}}}^{(i)})|. \end{aligned} \end{aligned}$$
(14)
Since the function \(x \mapsto (j-1-\log x )\,x\) is increasing for \(0<x\le 2^{j-1-1/\ln 2} \approx 2^{j-2.442}\), and \(|S({{\mathcal {D}}}^{(i)})| \le \zeta ^{i-1} t < 2^{j-3}\) for every \(i=2,\dots ,s\) and for \(\zeta = 1/32\), we can bound the last expression in (14) by replacing \(|S({{\mathcal {D}}}^{(i)})|\) with \(\zeta ^{i-1} t\), for every \(i=2,\dots ,s\), so we get that
$$\begin{aligned} b\sum _{i=2}^s \bigl (j-1-\log |S({{\mathcal {D}}}^{(i)})|\bigr ) | S({{\mathcal {D}}}^{(i)}) |\le b\sum _{i=2}^s \bigl (j- 1-\log (\zeta ^{i-1} t)\bigr ) \,\zeta ^{i-1} t. \end{aligned}$$
Since \(t\ge 2^{j-1}\), we can bound the right-hand side by
$$\begin{aligned} -bt\sum _{i=2}^s \zeta ^{i-1}\log {\zeta ^{i-1}} = bt\log \frac{1}{\zeta }\sum _{i=2}^s (i-1) \,\zeta ^{i-1}\le 5bt\sum _{i=1}^\infty i\zeta ^{i}= \frac{5bt\zeta }{(1-\zeta )^2}. \end{aligned}$$
We conclude that, for \(\zeta ={1}/{32}\), the sum is smaller than bt/6, so we still have more than
$$\begin{aligned} bt\biggl (\frac{1}{4} - \frac{1}{32} \biggr ) - \frac{bt}{6} =\frac{5bt}{96} \end{aligned}$$
free credits. By construction, this free credit is \(\Psi ^- - \Psi ^+ = -\Delta \Psi \), to which we add the bw credits we gave h upon insertion. Hence, if b is large enough, say at least 20, we have \(bw - \Delta \Psi \ge t\). Since the real insertion cost is at most t credits, it follows that the released credit suffices to pay for the real insertion cost (with change to spare), and the lemma follows. \(\square \)
Corollary 7.4
The overall cost of n insertions is \(O(n\log ^3n)\).
Proof
As already mentioned, we ignore the changes in the size of the credits caused by doublings of N; as noted, this adds only \(O(n\log ^2n)\) to the overall cost. We add up the inequalities (13), over all insertions, and get that the overall actual cost of the insertions plus \(\Psi _{\text {final}} - \Psi _{\text {initial}}\), is at most \(O(nw\log ^2n) = O(n\log ^3n)\). Since \(\Psi _\text {final} - \Psi _\text {initial} \ge 0\), this also bounds the actual cost of n insertions. \(\square \)
We note that Chan’s recent improvement [14] follows from this corollary, simply by reducing the size of a single credit to \(O(\log N)\), and leaving the rest of the analysis intact. The following lemma summarizes the properties of our insertion-only structure.
Lemma 7.5
The deterministic amortized cost of an insertion is \(O(\log ^3n)\), and the deterministic worst-case cost of a query is \(O(\log ^2 n)\).
Handling Deletions
Finally, we describe how to maintain the lower envelope of a set H of non-vertical planes in \({{\mathbb {R}}}^3\) under insertions and deletions. As before, we denote the current number of planes in the data structure by n, and we use N to denote the power of 2 with \(n \in [N, 2N)\). Now we add a global rebuilding mechanism: whenever the number of updates (insertions and deletions) since the last global rebuild becomes N/2, we completely rebuild the data structure from scratch for the current set H, and we adjust (double or half) the value of N, if needed, to restore the size range invariant.Footnote 22 We will argue later that the overall cost of the rebuildings is subsumed in (and actually much smaller than) the cost of the other steps of the algorithm.
The basic organization of the data structure is the same as in Sect. 7.2, consisting of a sequence of bins \({{\mathcal {I}}}= ({{\mathcal {B}}}_{i_0},{{\mathcal {B}}}_{i_1},\dots ,{{\mathcal {B}}}_{i_k})\), where \(0\le i_0< i_1< \ldots < i_k \), occupied by substructures of some static structures. For each such substructure, we continue to denote by \(C({{\mathcal {B}}}_j)\) the set of planes that it was constructed from, and by \(S({{\mathcal {B}}}_j)\subseteq C({{\mathcal {B}}}_j)\) the subset of planes that survived (are stored) in it.Footnote 23
Insertions and queries are performed in much the same way as in Sect. 7.2, although some aspects of their implementation and analysis are different; see below for details. We delete a plane h by visiting each substructure \({{\mathcal {B}}}_j\) with \(h \in C({{\mathcal {B}}}_j)\), and marking h as deleted in each conflict list of \({{\mathcal {B}}}_j\) that contains h (note that this is done also for substructures in which h has not survived the initial construction, because it was pruned at some level of the hierarchy). Each plane can get marked, at the time it is deleted, up to \(O(\log ^2n)\) times, once for each conflict list that contains it at the time when the deletion takes place. (Recall that, at each \({{\mathcal {B}}}_j\) with \(h\in C({{\mathcal {B}}}_j)\), h appears in at most \(O(\log n)\) (pruned) conflict lists, over the entire hierarchy constructed at \({{\mathcal {B}}}_j\).)
Actual removal of h, albeit possibly only from some of the substructures, takes place during a global rebuild or when pieces of the data structure are rebuilt, either during an insertion of a new plane, or at certain steps of the procedure where conflict lists are purged and their elements are reinserted; see below for details.
For a substructure \({{\mathcal {B}}}_i\), we denote by \(A({{\mathcal {B}}}_i) \subseteq S({{\mathcal {B}}}_i)\) the set of active planes in \({{\mathcal {B}}}_i\), defined as those planes that (a) are in \(S({{\mathcal {B}}}_i)\), (b) have not been (marked as) deleted, and (c) have not been reinserted into other substructures due to the lookahead deletion mechanism, which we describe next. When a substructure \({{\mathcal {B}}}_i\) is created, we have \(A({{\mathcal {B}}}_i) = S({{\mathcal {B}}}_i)\). Once \({{\mathcal {B}}}_{i}\) is created, its associated sets \(C({{\mathcal {B}}}_{i})\) and \(S({{\mathcal {B}}}_i)\), as well as all non-purged conflict lists \({{\,\mathrm{CL}\,}}(\tau )\) of prisms \(\tau \) in (any hierarchical stage within) \({{\mathcal {B}}}_i\), remain fixed, until \({{\mathcal {B}}}_i\) is destroyed (in a rebuild triggered by an insertion or a reinsertion, or in a global rebuild). On the other hand, conflict lists may be marked as purged by the lookahead deletion mechanism, and the set \(A({{\mathcal {B}}}_i)\) of active planes in \({{\mathcal {B}}}_i\) may get smaller, due to deletions and the purging of conflict lists.
Lookahead deletions When too many planes in a conflict list \({{\,\mathrm{CL}\,}}(\tau )\), for some prism \(\tau \), are (marked as) deleted, the real lower envelope of H might rise too high, and the lowest (undeleted) plane over a query point q (with q lying in the projection of \(\tau \)) does no longer have to belong to \({{\,\mathrm{CL}\,}}(\tau )\). (Note that if \(\tau \) belongs to the lowest-indexed cutting of some structure \({{\mathcal {B}}}_j\), which is the only kind of prisms we access when processing a query, its ceiling lies above level \(k_0\) of the corresponding set of planes, so, even after \(k_0-1\) deletions from that set, the lowest plane over q still belongs to \({{\,\mathrm{CL}\,}}(\tau )\), but a larger number of deletions may cause the difficulty just noted to arise.)
To avoid this situation, which might cause us to miss the correct answer to a query, we use the following lookahead deletion mechanism. Suppose that, for some prism \(\tau \) in a cutting \(\Lambda _i\) of some substructure \({{\mathcal {B}}}_j\), at least \(|{{{\,\mathrm{CL}\,}}(\tau )}|/(2\alpha )\) planes in \({{\,\mathrm{CL}\,}}(\tau )\) have been marked as deleted,Footnote 24 where \(\alpha >1\) is our cutting parameter (i.e., each prism of \(\Lambda _i\) is intersected by at most \(\alpha k_i = 2^i\alpha k_0\) planes, for any i). Then we purge the conflict list \({{\,\mathrm{CL}\,}}(\tau )\), and we reinsert (only) the planes in \({{\,\mathrm{CL}\,}}(\tau ) \cap A({{\mathcal {B}}}_i)\), one by one, using the standard insertion algorithm. After this, \(A({{\mathcal {B}}}_i)\) contains no more elements from \({{\,\mathrm{CL}\,}}(\tau )\), but elements from \({{\,\mathrm{CL}\,}}(\tau )\) may still appear in other conflict lists of \({{\mathcal {B}}}_i\) and in \(S({{\mathcal {B}}}_i)\). We keep the purged prism \(\tau \) in \({{\mathcal {B}}}_i\); whenever a query accesses \(\tau \) (when \(\tau \) is a prism of the lowest-indexed cutting of some substructure), it realizes that \({{\,\mathrm{CL}\,}}(\tau )\) is purged and simply skips it. A plane h may be reinserted many times due to the purging of a conflict list, but only once for each substructure \({{\mathcal {B}}}_i\) in which it is active (prior to the operation). Also, the planes in \(C({{\mathcal {B}}}_i){\setminus } S({{\mathcal {B}}}_i)\), and the planes marked as deleted will never be reinserted when a conflict list is purged.
As mentioned, queries and insertions are handled as in Sect. 7.2. For queries, while processing a substructure \({{\mathcal {B}}}_i\) and searching in the conflict list of some prism \(\tau \) of the lowest-indexed cutting \(\Lambda _0\) of \({{\mathcal {B}}}_i\), we only consider planes in \({{\,\mathrm{CL}\,}}(\tau ) \cap A({{\mathcal {B}}}_i)\), and report the lowest among them over the query point. As we will show later, in Lemma 7.6, this suffices to retrieve the correct overall lowest plane. That is, the plane that is lowest over q among the reported planes is the overall lowest plane over q.
To insert a plane h, we take, as in Sect. 7.2, the largest contiguous prefix \({{\mathcal {I}}}'\) of occupied bins in \({{\mathcal {I}}}\), of some length j, discard the existing structures in \({{\mathcal {I}}}'\), setFootnote 25\({H}_j :=\{h\} \cup \bigcup _{i=0}^{j-1} A({{\mathcal {B}}}_{i}) \), construct a new static structure for \({H}_j\), and spread its substructures within some bins of \({{\mathcal {I}}}'\), according to the rules of Sect. 7.2. A plane \(h\in {H}_j\) is active after the insertion (only) at the bin where it is stored.
Since we perform the reconstruction of the structure only on the active planes in the various destroyed substructures, the planes marked as deleted really disappear at this step, but only from the structures stored at the bins of \({{\mathcal {I}}}'\); such a plane might still show up (marked as deleted) in substructures \({{\mathcal {B}}}_\ell \) with larger bin indices \(\ell \), which have not been touched by this instance of the insertion procedure.
It is easy to prove, by induction on the number of operations, that the following invariants are maintained:
-
(D1)
For each i, we have \(2^{i-1} < |S({{\mathcal {B}}}_{i})| \le 2^{i}\).
-
(D2)
The sets \(A({{\mathcal {B}}}_{i})\subseteq S({{\mathcal {B}}}_{i})\) are pairwise disjoint, and their union is H.
Indeed, invariant (D1) is the same as invariant (I1), and its maintenance is argued as in Sect. 7.2. Invariant (D2) follows because, by induction, a plane h is active, before the current operation, at exactly one bin. If we delete h then the invariant continues to hold, as h no longer belongs to H. If we purge h from a conflict list in some substructure \({{\mathcal {B}}}_i\), it is no longer active in \({{\mathcal {B}}}_i\), but its reinsertion makes it active again, at the unique bin where it is stored. The same reasoning applies to all planes that were active at the bins that were destroyed by the reinsertion, and a similar reasoning holds when we insert (rather than reinsert) a plane.
Note though that the lower bound (11) of Sect. 7.2 does not have to hold now, as the number of active planes may be much smaller that the number of stored planes. The upper bound (12) remains valid, and so does Lemma 7.2. The correctness of the data structure is a consequence of the following lemma.
Lemma 7.6
Let \(q \in {{\mathbb {R}}}^2\), and let \(h \in H\) be a (non-deleted) plane on the lower envelope of H over q (for most queries, h is unique). Let \({{\mathcal {B}}}_i\) be the unique substructure for which \(h \in A({{\mathcal {B}}}_i)\). Then h belongs to the conflict list \({{\,\mathrm{CL}\,}}(\tau )\) of the prism \(\tau \) of the lowest-indexed cutting \(\Lambda _0\) of \({{\mathcal {B}}}_i\), whose xy-projection contains q, and \(\tau \) has not been marked as purged.
Proof
The second part of the claim is an immediate consequence of the first part, since h is active in \({{\mathcal {B}}}_i\).
Assume to the contrary that \(h \notin {{\,\mathrm{CL}\,}}(\tau )\). Let \(q^+\) be the point on h over q. By assumption, \(q^+\) lies on the lower envelope of H, and since \(h \not \in {{\,\mathrm{CL}\,}}(\tau )\), but \(h \in A({{\mathcal {B}}}_i) \subseteq S({{\mathcal {B}}}_i)\), we have that h does not cross \(\tau \), so the point \(q^+\) lies above \(\tau \). Let t be the largest index for which \(q^+\) lies above the top terrain \({\overline{\Lambda }}_t\) of the cutting \(\Lambda _t\) of \({{\mathcal {B}}}_i\); by what we have just argued, such a t exists, and it is possible that \(t=m\) (the total number of real terrains in \({{\mathcal {B}}}_i\)), but \(t\ne m+1\). Let \(\tau '\) be the prism of \(\Lambda _t\) for which \(q^+\) lies above the ceiling \({\overline{\tau }}'\), or, equivalently, q lies in the xy-projection of \(\tau '\).Footnote 26 Since \(\Lambda _t\) is a shallow cutting of \(L_{\le k_t}(H_t)\), for a suitable set of planes \(H_t\), we have that \({\overline{\Lambda }}_t\) lies fully above \(L_{k_t}(H_t)\). Thus, at least \(k_t\) planes of \(H_t\) pass below \(q^+\), and we denote the set of these planes as \({{\,\mathrm{CL}\,}}(q^+)\). Since \(q^+\) now lies on the lower envelope of H, all the (at least \(k_t\)) planes of \({{\,\mathrm{CL}\,}}(q^+)\) must have been (marked as) deleted from H.
Note that it is possible that \({{\,\mathrm{CL}\,}}(\tau ')\) has already been purged by the lookahead deletion mechanism. Note also that we do not necessarily have \({{\,\mathrm{CL}\,}}(q^+) \subseteq {{\,\mathrm{CL}\,}}(\tau ')\), as some planes from \(H_t\) may have appeared in too many conflict lists after the construction of \(\Lambda _t\) and may have been removed by the pruning mechanism from the conflict list of \(\Lambda _t\).
Consider now the prism \(\tau ''\) of \(\Lambda _{t+1}\) that contains \(q^+\) (with \(\tau '' = {{\mathbb {R}}}^3\), if \(t=m\)). Since \({{\,\mathrm{CL}\,}}(q^+)\subseteq H_t\), none of its planes were pruned earlier, before constructing \(\Lambda _{t}\). Consequently, \({{\,\mathrm{CL}\,}}(q^+) \subseteq {{\,\mathrm{CL}\,}}(\tau '')\) and, by definition of \(q^+\), \(h\in {{\,\mathrm{CL}\,}}(\tau '')\).Footnote 27 In the extreme case \(t=m\) we take \(\tau ''\), as just mentioned, to be the entire 3-space, and then \(H_t\subseteq {{\,\mathrm{CL}\,}}(\tau '')\). If \(t < m\), we have \(|{{{\,\mathrm{CL}\,}}(\tau '')}| \le \alpha k_{t+1}=2\alpha k_t\), and if \(t = m\), we have \(|{{{\,\mathrm{CL}\,}}(\tau '')}| = n \le 2\alpha k_m\). Hence, by the time \(q^+\) has reached the lower envelope of H, at least
$$\begin{aligned} |{{{\,\mathrm{CL}\,}}(q^+)}|\ge k_t \ge \frac{|{{{\,\mathrm{CL}\,}}(\tau '')}|}{2\alpha } \end{aligned}$$
planes of \({{\,\mathrm{CL}\,}}(\tau '')\) have been marked as deleted. Thus, the lookahead deletion mechanism should have purged \({{\,\mathrm{CL}\,}}(\tau '')\), which contains h, but h is still in \(A({{\mathcal {B}}}_i)\), a contradiction that establishes the claim. \(\square \)
The following lemma analyzes the performance of the data structure.
Lemma 7.7
The amortized deterministic cost of an insertion is \(O(\log ^3n)\), the amortized deterministic cost of a deletion is \(O(\log ^5n)\), and the worst-case deterministic cost of a query is \(O(\log ^2n)\).
Proof
The bound on the query time follows as in Lemma 7.5.
Insertions Consider an insertion of a plane h. As in Sect. 7.2, each plane that is in H (i.e., has not been marked as deleted) holds \(b\,(w-i)\)credits, each worth \(a\log ^2N\)units, where i is the current unique location (bin index) of the structure \({{\mathcal {B}}}_i\) for which \(h\in A({{\mathcal {B}}}_i)\), and \(w:= \log N + 2\) bounds, by Lemma 7.2, the maximum length of \({{\mathcal {I}}}\). Here a is as defined in Sect. 7.2, and b is another constant parameter that will be chosen later.
We modify the analysis in Lemma 7.5 as follows. Let j be, as before, the index of the first empty bin just before the insertion, and let \({H}_j := \{h\}\cup \bigcup _{i=0}^{j-1} A({{\mathcal {B}}}_{i})\). Define \(s = |{H}_j|\) and \(t = \sum _{i=0}^{j-1} |S({{\mathcal {B}}}_{i})| + 1\). As in (11) and (12), using invariant (D1) (which is identical to invariant (I1)), we get that \(2^{j-1} < t\le 2^j\). On the other hand, as already remarked, it is possible that \(s\ll t\), which may cause us to place the newly constructed substructures \({{\mathcal {D}}}^{(u)}\) in bins of rather small indices. The active planes in these bins will then require a larger number of credits, which the scheme in Sect. 7.2 cannot provide.
To cover the cost of an insertion in such a case, we observe that \(s \ll t\) means that most elements in the structures that are destroyed by the insertion are not active in their respective structures. That is, they either are not stored in their substructure (call it \({{\mathcal {B}}}_i\)), are (marked as) deleted, or were contained in a conflict list of \({{\mathcal {B}}}_i\) that has been purged. To exploit this observation, we proceed as follows. Consider some substructure \({{\mathcal {B}}}_i\), and let \(\tau \) be a prism in \({{\mathcal {B}}}_i\) (at any level of the hierarchy). If the conflict list of \(\tau \) has not been purged, we denote by \(D(\tau )\) the number of planes in \({{\,\mathrm{CL}\,}}(\tau )\) that have been (marked as) deleted.Footnote 28 We define the potential of \({{\mathcal {B}}}_i\) to be
$$\begin{aligned} \Psi ({{\mathcal {B}}}_i) = \left( b' \sum _{\tau \in \Pi _{\lnot p}^{(i)}} D(\tau )\, +\,b'' \sum _{\tau \in \Pi _p^{(i)}} |{{{\,\mathrm{CL}\,}}(\tau )}|\right) \log N \end{aligned}$$
(15)
credits, where \(b'\) and \(b''\), with \(b' > b''\), are suitable multiples of b, to be set later, \(\Pi _{\lnot p}^{(i)}\) denotes the set of all non-purged prisms in \({{\mathcal {B}}}_i\), and \(\Pi _p^{(i)}\) is the set of all purged prisms in \({{\mathcal {B}}}_i\). We emphasize once again that \(|{{{\,\mathrm{CL}\,}}(\tau )}|\) denotes the original size of the conflict list, as it was constructed. The purpose of this potential is to provide the credit for the increase in potential (when the number of active planes in the destroyed substructures is small) and to pay for the reinsertions (when a conflict list is purged). The overall potential \(\Psi ^*\) of the structure, measured in credits (rather than in units of credit), is defined as
$$\begin{aligned} \Psi ^* = \Psi + \sum _{i\ge 0} \Psi ({{\mathcal {B}}}_i) , \end{aligned}$$
where \(\Psi \) is the overall number of credits held by the planes in H, as explained above. As mentioned, every plane counted by t but not by s has either been marked as deleted or was contained in a conflict list that has been purged. Thus
$$\begin{aligned} t - s \,\le \,\sum _{i = 0}^{j - 1} \left( \sum _{\tau \in \Pi _{\lnot p}^{(i)}} D(\tau ) +\sum _{\tau \in \Pi _p^{(i)}} |{{{\,\mathrm{CL}\,}}(\tau )}|\right) . \end{aligned}$$
The following two cases can arise:
Case (a): \(s < (1-\zeta )\,t\). In this case \(t-s > {\zeta }s/({1-\zeta })\); that is,
$$\begin{aligned} \sum _{i = 0}^{j - 1} \left( \sum _{\tau \in \Pi _{\lnot p}^{(i)}} D(\tau )\, + \sum _{\tau \in \Pi _p^{(i)}} |{{{\,\mathrm{CL}\,}}(\tau )}|\right) >\frac{s}{31} , \end{aligned}$$
or, with a suitable choice of \(b''\), and recalling that \(b' > b''\),
$$\begin{aligned} \sum _{i=0}^{j-1} \Psi ({{\mathcal {B}}}_i) > \frac{b''s}{31}\log N. \end{aligned}$$
Since all these substructures are now destroyed, this potential will no longer appear in the full potential \(\Psi ^*\), and we can safely use it to cover the cost of the insertion. As described in Sect. 7.2, for a sufficiently large constant \(b''\), this will enable us to place the s planes of \({H}_j\) at the bins they are to be stored in, no matter where, with the correct amount of credit assigned to each of them (and with change to spare).
Case (b): \(s \ge (1-\zeta )\,t\). Then
$$\begin{aligned} |S({{\mathcal {D}}}^{(1)})| \ge (1-\zeta )\,s\ge (1-\zeta )^2\,t\ge (1-\zeta )^2\,2^{j-1} > 2^{j-2} \end{aligned}$$
(which holds for \(\zeta = 1/32\)), implying that \({{\mathcal {D}}}^{(1)}\) is stored at bin j or \(j-1\). (Note that, right after the reconstruction caused by an insertion, \(A({{\mathcal {D}}}^{(j)}) = S({{\mathcal {D}}}^{(j)})\) for each of the newly constructed substructures \({{\mathcal {D}}}^{(j)}\).) Furthermore, the lower bound in invariants (D1) and our assumption that \(s \ge (1-\zeta )\,t\) show that at least \(\sum _{i=1}^{j-2}2^{i-1} + 2-\zeta t = 2^{j-2}-\zeta t\ge t/4-\zeta t\) planes in \({H}_j\) were stored at bins \(i=0,1,\dots , j-2\) prior to the insertion. By Lemma 7.1, the reconstruction following the insertion passes at most \(\zeta s \le \zeta t\) of them to bins of indices \(0,1,\dots ,j-2\), so at least \(t/4-2\zeta t\) of these planes end up at \({{\mathcal {B}}}_j\) or \({{\mathcal {B}}}_{j-1}\). These planes release at least \(bt\,(1/4 -2\zeta )\) credits.
The other planes, that are passed to lower-indexed bins, may require additional credits, but the total number of these credits is bounded as in the proof of Lemma 7.5. It follows that for our choice of \(\zeta = 1/32\) and for a somewhat larger choice of b (than the one in Sect. 7.2), the released credit suffices to pay for the real insertion cost. In all the newly constructed substructures \({{\mathcal {B}}}_i\), we have \(S({{\mathcal {B}}}_i) = A({{\mathcal {B}}}_i)\), and no conflict list has been purged, so, by definition, \(\Psi ({{\mathcal {B}}}_i) = 0\); in other words, no credits have to be reallocated for these potentials.
In conclusion, in either of the two cases, the actual cost of the insertion, plus the difference in \(\Psi ^*\), is upper bounded by the amortized cost, which, as in Sect. 7.2, is bw credits, or \(O(\log ^3n)\) units of credit.
Deletions Finally, we analyze the amortized deletion cost. When we delete a plane h from H, we give it \(b'_0\log ^3N\) credits, where \(b'_0\) is some sufficiently large multiple of \(b'\), that is, \(\Theta (\log ^5N)\) units of credit. To each conflict list \({{\,\mathrm{CL}\,}}(\tau )\) with \(h \in {{\,\mathrm{CL}\,}}(\tau )\), that has not been purged yet, we allocate, from the credit given to h, \(b' \log N\) credits to account for the increase in potential due to the deletion of h (this increase is reflected in (15)). There are at most \(c\log N\) such lists in each of the \(O(\log N)\) substructures \({{\mathcal {B}}}_i\), so there are enough credits to account for the increase in potential.
The marking of h as deleted may lead, via the lookahead deletion mechanism, to the purging of several conflict lists containing h, and to the reinsertion of the active planes in these conflict lists. Let \({{\,\mathrm{CL}\,}}(\tau )\) be a conflict list in some substructure \({{\mathcal {B}}}_i\) that is purged when h is deleted. At this point there are at least \(|{{{\,\mathrm{CL}\,}}(\tau )}|/{(2\alpha )}\) planes in \({{\,\mathrm{CL}\,}}(\tau )\) that have been marked as deleted, and the status of \({{\,\mathrm{CL}\,}}(\tau )\) switches from non-purged to purged. Thus, this switch releases (again, recall (15))
$$\begin{aligned} (b' D(\tau )- b'' |{{{\,\mathrm{CL}\,}}(\tau )}|) \log N\ge \biggl (\frac{b'}{2\alpha }- b''\biggr ) |{{{\,\mathrm{CL}\,}}(\tau )}|\log N \end{aligned}$$
credits. The reinsertion itself proceeds exactly as in the case of insertion. With a suitable choice of \(b'\) and \(b''\), say \(b'\ge 4\alpha b''\) and \(b''\) sufficiently large, the \(\Theta (\log N)\) credits needed to support each of the at most \(|{{{\,\mathrm{CL}\,}}(\tau )}|\) reinsertions are thus available, including the \(\Theta (\log N)\) credits that each reinserted plane has to bring along. This implies, as in Sect. 7.2, that the amortized cost of a deletion is indeed \(O(\log ^3N)\) credits, or \(O(\log ^5N)\) units.
Each global rebuilding occurs after \(\Theta (N)\) updates (insertions and deletions), which have occurred since the last global rebuilding. In the rebuilding, all lingering (marked as) deleted planes are fully removed from the structure. All other planes abandon their present status, and we simply build a static structure from the current planes, storing its substructures at a suitable sequence of bins. The cost of the rebuilding is \(O(N\log ^2N)\), so the total cost of all rebuildings is \(O(n\log ^2n)\), where n is the total number of updates, plus the size of the initial set of planes (if nonempty). This is well subsumed by the overall amortized cost of the insertions and deletions. \(\square \)
Storage So far, the structure requires \(O(n\log n)\) cells of storage: \({{\mathcal {I}}}\) has \(O(\log n)\) substructures, where the substructure \({{\mathcal {B}}}_i\) at index i is a hierarchy of cuttings, each approximating some level in a geometric sequence of levels (of suitable subsets of H). Put \(n_i:= |C({{\mathcal {B}}}_i)|\le 2^i\). The number of prisms in the cutting for level k is \(O(n_i/k)\), and the size of each conflict list is O(k), so the total storage for each level of \({{\mathcal {B}}}_i\) is \(O(n_i)\), for a total storage of \(O(n_i\log n_i)\). Summing over i, the total storage is \(O(n\log n)\). A similar analysis shows that the total storage, excluding the conflict lists, is O(n).
Using an idea that is credited to Afshani by Chan [13], we can improve the storage to linear, if for each conflict list we store only its initial size and the number of planes that were deleted in it (except for the lowest-indexed cuttings, where we keep the conflict lists explicitly, but the size of any such lowest-indexed list is only O(1)). Then, the storage for \({{\mathcal {B}}}_j\) is \(O(n_j)\), making the overall storage O(n). To make this work, we need additional mechanisms to compensate for the missing conflict lists. Specifically, when we delete a plane h, we need to find the conflict lists that contain h, and increment the deletion counter of each corresponding prism. Naively, within a substructure \({{\mathcal {B}}}_i\), the plane h has to find all the vertices of all the cuttings that lie above it. Each such vertex is a vertex of some prism(s), and h belongs to the conflict list of each such prism. However, h might lie below a vertex v and not belong to the conflict lists of the incident prisms, because h has been pruned away while processing the current or a higher-indexed cutting.
Thus, we augment \({{\mathcal {B}}}_j\) with a separate halfspace range reporting data structure for the set of vertices of each of its cuttings. We use the recent algorithm of Afshani and Chan [1] (which can be made deterministic by using the shallow cutting construction of [16]), which preprocesses a set V of points in \({{\mathbb {R}}}^3\), in \(O(|V|\log |V|)\) time, into a data structure of linear size, so that the set of those points of V that lie above a querying plane h can be reported in \(O(\log |V| + t)\) time, with t being the output size. The cost of augmenting \({{\mathcal {B}}}_i\) with these reporting structures is subsumed by the cost of building \({{\mathcal {B}}}_i\) itself. Now, when deleting a plane h, we access each substructure \({{\mathcal {B}}}_i\) of \({{\mathcal {I}}}\) with \(h \in C({{\mathcal {B}}}_i)\). For this, each plane h stores pointers to all these structures. Since the overall size of the sets \({{\mathcal {C}}}({{\mathcal {B}}}_i)\) is O(n), the overall number of such pointers is linear. For each substructure \({{\mathcal {B}}}_i\) with \(h \in C({{\mathcal {B}}}_i)\), we find the prisms that contain h in their conflict lists. To ensure correctness of this step, h also stores a second pointer, for each \({{\mathcal {B}}}_i\) containing it, to the level at which it was pruned; if h was not pruned, we store a null pointer. Now h accesses the halfspace range reporting structures of all the levels higher than the level at which h was pruned, and retrieves from each of these structures the prisms that contain it in their conflict lists. For each such prism \(\tau \), we increment its deletion counter by 1. If the counter becomes too large relative to the initial size, as explained above, we purge the entire conflict list, and reinsert its surviving active members into the structure (of course, this step also requires a data structure to be performed efficiently, see below). The total cost of these steps, excluding the one that purges conflict lists that have become too small, is \(O(\log ^3n + t)\), where t is the overall number of prisms that store h in their conflict lists. The term \(O(\log ^3n)\) arises since we access up to \(O(\log n)\) substructures \({{\mathcal {B}}}_i\), access up to \(O(\log n)\) halfspace range reporting structures at each of them, and pay an overhead of \(O(\log n)\) for querying in each of them. Since, by construction, \(t=O(\log ^2n)\), this modification, so far, adds \(O(\log ^3n)\) to the total of cost of a deletion.
As noted, we also require a mechanism to compute the active members of the conflict lists that are purged in a substructure \({{\mathcal {B}}}_i\). To do so, we preprocess the planes of \(S({{\mathcal {B}}}_i)\) into a (dual version of a) halfspace reporting data structure that we keep with \({{\mathcal {B}}}_i\). We query this structure with each of the at most four vertices of \(\tau \), to obtain, in an output-sensitive manner, all the planes of \(S({{\mathcal {B}}}_i)\) that cross \(\tau \). This structure takes space linear in \(|S({{\mathcal {B}}}_i)|\), \(O(|S({{\mathcal {B}}}_i)| \log |S({{\mathcal {B}}}_i)|)\) time to build, and can answer a query in \(O(\log |S({{\mathcal {B}}}_i)| + t)\) time, where t is the output size. The cost of answering such a query is subsumed by the cost of reinserting the planes, and the cost of constructing this reporting structure is subsumed by the cost of constructing \({{\mathcal {B}}}_i\). We thus obtain the following main summary result of this section.
Theorem 7.8
The lower envelope of a set of n non-vertical planes in three dimensions can be maintained dynamically, so as to support insertions, deletions, and queries, so that each insertion takes \(O(\log ^3n)\) amortized deterministic time, each deletion takes \(O(\log ^5n)\) amortized deterministic time, and each query takes \(O(\log ^2n)\) worst-case deterministic time, where n is the size of the set of planes at the time the operation is performed. The data structure requires O(n) storage.