cs0210006/cs0210006
1: \documentclass[12pt]{article}
2: \usepackage{fullpage}
3: \usepackage{latexsym,amssymb}
4: \newcommand{\flow}{\mb{{\sc flow}}}
5: \newcommand{\Struc}{\mb{STRUCTURED}}
6: \newcommand{\mb}[1]{\mbox{#1}}
7: \newcommand{\prd}{\rightarrow}
8: \newcommand{\D}[2]{T[#1, #2]}
9: \newcommand{\NP}{{{\cal NP}}}
10: \newcommand{\Addr}[2]{{{\cal A}^{#2}(#1)}}
11: \newcommand{\Ult}[1]{{{\cal U}(#1)}}
12: \newcommand{\Ultr}[2]{{{\cal U}^{#2}(#1)}}
13: %\newcommand{\Approx}{\rm Approx}
14: \newcommand{\basis}[1]{{\tt basis}(#1)}
15: \newcommand {\norm}[2]{\mbox{$\parallel #1 \parallel_{#2}$}}
16: \newcommand{\iteml}[1]{\item\label{#1}}
17: \newcommand{\Label}[1]{\label{#1}\mbox{(\bf {#1})}}
18: \newenvironment{LABS}{\begin{list}{}{}}{\end{list}}
19: \newcommand{\LAB}[1]{\item[{#1}]}
20: \newtheorem{procedure}{Procedure}
21: %\newcommand{\polylog}{{\rm\, polylog\,}}
22: \newcommand{\degree}{{\rm degree}}
23: \newcommand{\fnctfont}[1]{\mbox{\tt {#1}}}
24: \newcommand{\procfont}[1]{\mbox{\sc {#1}}}
25: \newcommand{\V}{\fnctfont{V}}
26: \newcommand{\subtree}{\fnctfont{t}}
27: \newcommand{\LCA}{\fnctfont{LCA}}
28: \newcommand{\TOP}{\fnctfont{TOP}}
29: \newcommand{\POP}{\fnctfont{POP}}
30: \newcommand{\Sidetrees}{\fnctfont{SideT}}
31: \newcommand{\SV}{\fnctfont{Side-V}}
32: \newcommand{\SL}{\fnctfont{Side-}\Labels}
33: \newcommand{\SSons}{\fnctfont{Side-}\Sons}
34: \newcommand{\Mast}{\fnctfont{mast}}
35: \newcommand{\Root}{\fnctfont{r}}
36: \newcommand{\Parent}{\fnctfont{p}}
37: %\newcommand{\Base}{\fnctfont{Base}}
38: \newcommand{\Sidemast}{\fnctfont{side-mast}}
39: \newcommand{\Sons}{\fnctfont{C}}
40: \newcommand{\Son}{\fnctfont{c}}
41: \newcommand{\Spines}{\fnctfont{Spines}}
42: \newcommand{\Time}{\fnctfont{time}}
43: \newcommand{\Here}{i}
44: \newcommand{\There}{\overline{\imath}}
45: \newcommand{\Either}{j}
46: \newcommand{\here}{_{\Here}}
47: \newcommand{\there}{_{\There}}
48: \newcommand{\either}{_{\Either}}
49: \newcommand{\teither}{_{\overline{\Either}}}
50: \newcommand{\COMPARE}{\procfont{Comp}}
51: %\newcommand{\COMPARE}{\procfont{Compare}}
52: %\newcommand{\COMPCOREBASE}{\procfont{Prep-Core-Base}}
53: \newcommand{\COMPCOREBASE}{\procfont{Core-Base}}
54: %\newcommand{\COMPCORETREES}{\procfont{Comp-Core-Trees}}
55: \newcommand{\COMPCORETREES}{\procfont{Core-Trees}}
56: \newcommand{\TREES}{\procfont{Trees}}
57: %\newcommand{\SIDETREES}{\procfont{Comp-Side-Trees}}
58: \newcommand{\SIDETREES}{\procfont{Side-Trees}}
59: %\newcommand{\SPINES}{\procfont{Comp-Spines}}
60: \newcommand{\SPINES}{\procfont{Spines}}
61: \newcommand{\cT}{{\cal T}}
62: \newcommand{\cC}{{\cal C}}
63: \newcommand{\cD}{{\cal D}}
64: \newcommand{\cG}{{\cal G}}
65: \newcommand{\cH}{{\cal H}}
66: \newcommand{\cI}{{\cal I}}
67: \newcommand{\cS}{{\cal S}}
68: \newcommand{\cP}{{\cal P}}
69: \newcommand{\cO}{{\cal O}}
70: \newcommand{\cE}{{\cal E}}
71: \newcommand{\cF}{{\cal F}}
72: \newcommand{\brC}{\breve{C}}
73: \newcommand{\brD}{\breve{D}}
74: \newcommand{\brT}{\breve{T}}
75: \newenvironment{algorithmref}[1]{\medskip\\
76: \noindent{\bf Algorithm {#1}:}\ 
77: \renewcommand{\nestlab}{#1}}{\renewcommand{\nestlab}{??}}
78: 
79: 
80: \newcommand{\UWBM}{\fnctfont{UWBM}}
81: \newcommand{\WBM}{\fnctfont{WBM}}
82: %\newcommand{\RMAST}{\fnctfont{mast}}
83: \newcommand{\parent}{\fnctfont{M}}
84: \newcommand{\Both}{\{0,1\}}
85: \newcommand{\Match}{\fnctfont{match}}
86: \newcommand{\Deg}{\fnctfont{d}}
87: \newcommand{\Diag}{\fnctfont{Diag}}
88: 
89: 
90: 
91: 
92: 
93: %\renewcommand{\O}[1]{\mbox{$O(#1)$}}
94: \newcommand{\union}{\cup}
95: \newcommand{\intersect}{\cap}
96: \newcommand{\qed}{\Box}
97: \newcommand{\Nat}{{\cal N}}
98: \newcommand{\Def}{\noindent {\bf Definition:\space}}
99: 
100: 
101: %\def\stp#1#2{\item[]{\sf Step \thealgo.#1: #2}\par}
102: %\def\pstp#1#2{\item[]{\sf Step \theproc.#1: #2}\par}
103: %
104: %\def\@begintheorem#1#2{\trivlist \item[\hskip \labelsep
105: %                                       \if#1{Claim} {\it #1\ #2}
106: %                                       \else{\bf #1\ #2}\fi]}
107: %\def\@opargbegintheorem#1#2#3{\trivlist
108: %      \item[\hskip \labelsep\if#1{Claim} {\it #1\ #2\ (#3)}
109: %                            \else{\bf #1\ #2\ (#3)}\fi]}
110: %\makeatother
111: %
112: %\def\reversel{\rule{1.2ex}{.1ex}\rule{.1ex}{1.2ex}}
113: 
114: \newtheorem{lemma}{Lemma}
115: \newtheorem{observation}[lemma]{Observation}
116: \newtheorem{proposition}[lemma]{Proposition}
117: \newtheorem{theorem}[lemma]{Theorem}
118: \newtheorem{fact}[lemma]{Fact}
119: \newtheorem{corollary}[lemma]{Corollary}
120: \newtheorem{definition}[lemma]{Definition}
121: \newtheorem{remark}[lemma]{Remark}
122: \newtheorem{claim}{\sc Claim}[lemma]
123: \newtheorem{invariant}{Invariant}[section]
124: \renewcommand{\theclaim}{\thelemma\Alph{claim}}
125: \renewcommand{\thefigure}{\thesection.\arabic{figure}}
126: 
127:  \newcommand{\blackslug}{\hbox{\hskip 1pt \vrule width 4pt height 8pt
128: depth 1.5pt \hskip 1pt}}
129:  \newcommand{\QED}{\quad\blackslug\lower 8.5pt\null}
130:  \newcommand{\smQED}{\quad
131:   \vrule width1pt height6pt depth-1pt \kern -1pt
132:   \vrule width4pt height6pt depth-5pt \kern -4pt
133:   \vrule width4pt height2pt depth-1pt \kern -1pt
134:   \vrule width1pt height6pt depth-1pt }
135:  \newenvironment{proof}{{\bf Proof:}}{\QED}
136:  \newenvironment{proofsk}{{\bf Proof (Sketch):}}{\QED}
137:  \newenvironment{clproof}{{\em Proof:}}{\smQED}
138:  \newcommand{\nfont}{\rm}
139:  \newcommand{\st}{\,|\;}
140:  \newcommand{\implies}{\Rightarrow}
141: 
142: \newcommand{\comment}[1]{\begin{quote}{\tt {#1}}\end{quote}}
143: \newcommand{\oldcomment}[1]{}
144: \newcommand{\junk}[1]{}
145: 
146:  \newcommand{\inter}{\cap}
147:  \newcommand{\setadd}[1]{\cup \{ #1 \}}
148:  \newcommand{\edge}{\relbar\joinrel\joinrel\relbar}
149: \def\nae{{\rm NAE}}
150: 
151: \newcommand{\leaf}[1]{{\cal L}(#1)}
152: \newcommand{\restrict}[2]{{\cal L}^{-1}(#1,#2)}
153: 
154: \renewcommand{\qed}{\hspace{1em}\hfill\rule{.5em}{.5em}}
155: \newcommand{\rubberskip}{\par\addvspace{\smallskipamount}}
156: \renewenvironment{proof}{\rubberskip\noindent{\bf Proof:}\ }{\qed
157: \rubberskip\noindent}
158: \newcommand{\newm}[1]{\mbox{\boldmath${#1}$}}
159: \newcommand{\new}{\bf\boldmath}
160: \newcommand{\opp}[2]{\{#1,#2\}}
161: \newcommand{\popp}[2]{(#1,#2)}
162: \newcommand{\sopp}[2]{#1\times #2}
163: 
164: 
165: \newcommand{\E}{\fnctfont{E}}
166: \renewcommand{\L}{\fnctfont{L}}
167: \newcommand{\lca}{\fnctfont{lca}}
168: %\renewcommand{\O}[1]{\mbox{$O(#1)$}}
169: %\newcommand{\RMAST}{\fnctfont{MAST}}
170: \newcommand{\MAST}{\fnctfont{MAST}}
171: \newcommand{\MWC}{\fnctfont{MWC}}
172: %\newcommand{\CRMAST}{\mbox{\tt C-RMAST}}
173: %\newcommand{\Rmast}{\fnctfont{mast}}
174: \newcommand{\kndMAST}{\mbox{$k/n/d$-$\MAST$}}
175: \newcommand{\UMAST}{\fnctfont{UMAST}}
176: \newcommand{\Umast}{\fnctfont{umast}}
177: \newcommand{\MWM}{\fnctfont{MWM}}
178: \newcommand{\NE}{\fnctfont{NE}}
179: \newcommand{\Meet}{\fnctfont{meet}}
180: \newcommand{\Labels}{\fnctfont{A}}
181: \newcommand{\A}{\Labels}
182: \newcommand{\cL}{\Labels}
183: \newcommand{\cA}{\Labels}
184: 
185: \newenvironment{Alist}{%
186: \begin{list}{$\bullet$}{%
187: \setlength\itemsep{0.0in}%
188: \setlength\parsep{0in}%
189: \setlength\topsep{0in}%
190: }}{%
191: \end{list}}
192: 
193: \newenvironment{Blist}{%
194: \begin{list}{$-$}{%
195: \setlength\itemsep{0.0in}%
196: \setlength\parsep{0in}%
197: \setlength\topsep{0in}%
198: }}{%
199: \end{list}}
200: 
201: \newenvironment{Clist}{%
202: \begin{list}{$*$}{%
203: \setlength\itemsep{0.0in}%
204: \setlength\parsep{0in}%
205: \setlength\topsep{0in}%
206: }}{%
207: \end{list}}
208: 
209: \newenvironment{Dlist}{%
210: \begin{list}{$\triangleright$}{%
211: \setlength\itemsep{0.0in}%
212: \setlength\parsep{0in}%
213: \setlength\topsep{0in}%
214: }}{%
215: \end{list}}
216: 
217: \newenvironment{Elist}{%
218: \begin{list}{$\diamond$}{%
219: \setlength\itemsep{0.0in}%
220: \setlength\parsep{0in}%
221: \setlength\topsep{0in}%
222: }}{%
223: \end{list}}
224: 
225: \newtheorem{freeaux}{}
226: \renewcommand{\thefreeaux}{}
227: \newenvironment{free}{\begin{freeaux}\hspace{-.9em}\rm}{\end{freeaux}}
228: \newcommand{\proofbox}{\rule{.5em}{.5em}}
229: \renewenvironment{proof}[1][Proof:]{\begin{free}{\bf {#1}}\ }{\ 
230: \hfill\proofbox\end{free}}
231: \newenvironment{correctness}{\begin{free}{\bf Correctness:}\ }{\ 
232: \hfill\proofbox\end{free}}
233: \newenvironment{pproof}[1]{\begin{free}{\bf Proof 
234: {#1}:}\ }{\ \hfill\proofbox\end{free}}
235: \newenvironment{subclaim}[1]{\begin{free}{\sc Claim}\
236: {#1}\ \ }{\end{free}}
237: \newenvironment{subproof}{\begin{free}{\sc Proof:}\ }{\ \hfill$\Box$\end{free}}
238: \newpage
239: \newcommand{\eps}{\varepsilon}
240: \newcommand{\ul}{\underline}
241: \newcommand{\fct}{\rightarrow}
242: %\newcommand{\naturals}{\mbox{\rm I\hspace{-3pt}N} }
243: \newcommand{\cN}{{\naturals}}
244: %\newcommand{\cN}{{\cal N}}
245: \newcommand{\cR}{{\reals}}
246: %\newcommand{\cR}{{\cal R}}
247: 
248: \newcommand{\Ts}{{\vec{T}}}
249: \newcommand{\Us}{{\vec{U}}}
250: \newcommand{\vs}{{\vec{v}}}
251: \newcommand{\cs}{{\vec{c}}}
252: \newcommand{\ws}{{\vec{w}}}
253: \newcommand{\us}{{\vec{u}}}
254: \newcommand{\ds}{{\vec{s}}}
255: \newcommand{\js}{{\vec{\delta}}}
256: \newcommand{\jsh}{{\Delta}}
257: \newcommand{\as}{\vec{a}}
258: \newcommand{\ash}{A}
259: %\newcommand{\dir}[2]{{(#1\rightarrow #2)}}
260: \newcommand{\dir}[2]{{(#1\triangleright #2)}}
261: %\newcommand{\compat}{\sqcap}
262: \newcommand{\compat}{\perp}
263: \newcommand{\lcaTs}{{\tt lca}^{\Ts}}
264: \newcommand{\MaxMatch}{\mbox{\tt Max-Match}}
265: \newenvironment{sketch}{\noindent {\bf Proof (sketch):}}{\QED}
266: 
267: 
268: 
269: \newcommand{\nestlab}{??}
270: \newcounter{algctr}\renewcommand{\thealgctr}{\Alph{algctr}}
271: %\newenvironment{algorithm}{\medskip\\\refstepcounter{algctr}
272: %\noindent{\bf Algorithm \thealgctr:}\ 
273: \newenvironment{algorithm}{\refstepcounter{algctr}
274: \paragraph{Algorithm \thealgctr:} 
275: \renewcommand{\nestlab}{\thealgctr}}{\renewcommand{\nestlab}{??}}
276: \newlength{\lwidth}\setlength{\lwidth}{-\labelsep}
277: \addtolength{\lwidth}{\leftmargini}
278: \newlength{\lwidthi}\setlength{\lwidthi}{\lwidth}
279: \newcounter{litemi}
280: \renewcommand{\thelitemi}{\nestlab.\arabic{litemi}}
281: \newenvironment{nesti}{
282: \begin{list}{\makebox[\lwidthi][l]{\thelitemi.}}{
283: \setlength\itemsep{0.05in}%
284: \setlength\parsep{0in}%
285: \setlength\topsep{0.05in}%
286: \usecounter{litemi}}}{
287: \end{list}}
288: \addtolength{\lwidth}{\leftmarginii}
289: \newlength{\lwidthii}\setlength{\lwidthii}{\lwidth}
290: \newlength{\itemind}\setlength{\itemind}{-\leftmargini}
291: \newlength{\itemindii}\setlength{\itemindii}{\itemind}
292: \newcounter{litemii}
293: \renewcommand{\thelitemii}{\thelitemi.\arabic{litemii}}
294: \newenvironment{nestii}{
295: \begin{list}{\makebox[\lwidthii][l]{\thelitemii.}}{
296: \setlength{\itemindent}{\itemindii}\usecounter{litemii}}}{
297: \end{list}}
298: \addtolength{\lwidth}{\leftmarginiii}
299: \newlength{\lwidthiii}\setlength{\lwidthiii}{\lwidth}
300: \addtolength{\itemind}{-\leftmarginii}
301: \newlength{\itemindiii}\setlength{\itemindiii}{\itemind}
302: \newcounter{litemiii}
303: \renewcommand{\thelitemiii}{\thelitemii.\arabic{litemiii}}
304: \newenvironment{nestiii}{
305: \begin{list}{\makebox[\lwidthiii][l]{\thelitemiii.}}{
306: \setlength{\itemindent}{\itemindiii}\usecounter{litemiii}}}{
307: \end{list}}
308: \addtolength{\lwidth}{\leftmarginiv}
309: \newlength{\lwidthiv}\setlength{\lwidthiv}{\lwidth}
310: \addtolength{\itemind}{-\leftmarginiii}
311: \newlength{\itemindiv}\setlength{\itemindiv}{\itemind}
312: \newcounter{litemiv}
313: \renewcommand{\thelitemiv}{\thelitemiii.\arabic{litemiv}}
314: \newenvironment{nestiv}{
315: \begin{list}{\makebox[\lwidthiv][l]{\thelitemiv.}}{
316: \setlength{\itemindent}{\itemindiv}\usecounter{litemiv}}}{
317: \end{list}}
318: \addtolength{\lwidth}{\leftmarginv}
319: \newlength{\lwidthv}\setlength{\lwidthv}{\lwidth}
320: \addtolength{\itemind}{-\leftmarginiv}
321: \newlength{\itemindv}\setlength{\itemindv}{\itemind}
322: \newcounter{litemv}
323: \renewcommand{\thelitemv}{\thelitemiv.\arabic{litemv}}
324: \newenvironment{nestv}{
325: \begin{list}{\makebox[\lwidthv][l]{\thelitemv.}}{
326: \setlength{\itemindent}{\itemindv}\usecounter{litemv}}}{
327: \end{list}}
328: 
329: 
330: \sloppy
331: %--------- proof of lemma and theorem, for appendix ----------
332: \newenvironment{proofl}[1]{\begin{free}{\bf Proof of Lemma~\ref{#1}:}\ }{\ 
333: \hfill\proofbox\end{free}}
334: \newenvironment{prooft}[1]{\begin{free}{\bf Proof of Theorem~\ref{#1}:}\ }{\ 
335: \hfill\proofbox\end{free}}
336: \newenvironment{proofc}[1]{\begin{free}{\bf Proof of Corollary~\ref{#1}:}\ }{\ 
337: \hfill\proofbox\end{free}}
338: \newenvironment{proofany}[2]{\noindent{\bf Proof of #1~\ref{#2}:\ }}{\hfill$\Box$ \\ \ \par}
339: %--------- hint of proof ------------------------------------
340: \newenvironment{proofhint}{\medskip
341: \noindent{\bf Hint of proof:\ }(For a detailed proof,
342: see the appendix)}{\hfill$\Box$ \\ \ \par}
343: %-------------------------------------------------------------
344: 
345: \newcommand{\req}[1]{(\ref{#1})}
346: \newcommand{\idiv}{\hbox{\sc div}}
347: \newcommand{\mod}{\hbox{\sc mod}}
348: \newcommand{\brackets}[1]{\left\{{#1}\right\}}
349: \newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil}
350: \newcommand{\high}{\mbox{high}}
351: \newcommand{\low}{\mbox{low}}
352: \newcommand{\lsbonly}{\mbox{lsb-only}}
353: \newcommand{\asgn}{\leftarrow}
354: \newcommand{\sleft}{\ll}
355: \newcommand{\sright}{{\gg}}
356: \newcommand{\Low}{{\tt low}}
357: \newcommand{\LOW}{{\tt LOW}}
358: \newcommand{\High}{{\tt high}}
359: \newcommand{\Sort}{\mbox{\tt sort}}
360: \newcommand{\Insert}{\mbox{\tt insert}}
361: \newcommand{\Left}{{\tt left}}
362: \newcommand{\Right}{{\tt right}}
363: \newcommand{\Delete}{\mbox{\tt delete}}
364: \newcommand{\Delmin}{\mbox{\tt delete-min}}
365: \newcommand{\Deckey}{\mbox{\tt decrease-key}}
366: \newcommand{\Extract}{\mbox{\tt extract-min}}
367: \newcommand{\Min}{\mbox{\tt min}}
368: \newcommand{\Fmin}{\mbox{\tt find-min}}
369: \newcommand{\New}{\mbox{\tt new}}
370: \newcommand{\approof}{\hfill$\clubsuit$}
371: \newcommand{\drop}[1]{}
372: 
373: \newif\ifcom
374: %\comfalse
375: \comtrue
376: 
377: \newenvironment{typedescr}{\refstepcounter{algctr}
378: \paragraph{Description \thealgctr:} 
379: \renewcommand{\nestlab}{\thealgctr}}{}
380: 
381: \newcommand{\ol}[1]{\overline{{#1}}}
382: %\newcommand{\ul}[1]{\underline{{#1}}}
383: \newcommand{\ttl}{\ul{{\tt 1}}}
384: \newcommand{\tto}{\ul{{\tt 0}}}
385: \newcommand{\Str}{{\tt str}}
386: \newcommand{\Int}{{\tt int}}
387: \newcommand{\Ones}[1]{\|{#1}\|_1}
388: \newcommand{\Spread}{{\tt Spread}}
389: \newcommand{\Collect}{{\tt Collect}}
390: \newcommand{\Mask}{{\tt Mask}}
391: \newcommand{\Multishift}{{\tt VectorShift}}
392: \newcommand{\Multicount}{{\tt VectorCount}}
393: \newcommand{\Multimult}{{\tt VectorMult}}
394: \newcommand{\Multiadd}{{\tt VectorAdd}}
395: \newcommand{\Mult}{{\tt Mult}}
396: % removed by Arne newcommand{\Add}{{\tt Add}}
397: \newcommand{\piece}[3]{{{#1}}\langle {{#2}}\rangle_{/{#3}}}
398: \newcommand{\lpiece}[3]{{{#1}}\langle {{#2}}\rangle_{{#3}}}
399: \newcommand{\codecom}[1]{$/*$ #1 $*/$}
400: \newcommand{\codereturn}[1]{\underline{return #1}}
401: \newcommand{\Sign}{{\tt Sign}}
402: \newcommand{\Compr}{{\tt Compress}}
403: \newcommand{\la}{\leftarrow}
404: \newcommand{\find}{{\tt Find}}
405: \newcommand{\ins}{{\tt Insert}}
406: \newcommand{\fail}{{\tt failure}}
407: \newcommand{\done}{{\tt done}}
408: \newcommand{\pos}[1]{{\tt pos}(#1)}
409: \newcommand{\points}[1]{\mbox{\tt points-to}(#1)}
410: \newcommand{\instr}[1]{{\tt {#1}}}
411: 
412: \newcommand{\aacom}[1]{\ifcom\begin{quote}AA:\ \tt{#1}\end{quote}\fi}
413: \newcommand{\aach}{\marginpar{AA}}
414: \newcommand{\mtcom}[1]{\ifcom\begin{quote}MT:\ \tt{#1}\end{quote}\fi}
415: \newcommand{\mtch}{}%{\marginpar{MT}}
416: 
417: \newcommand{\xor}{\oplus}
418: \newcommand{\XOR}{\bigoplus}
419: 
420: \newcommand{\case}[1]{\underline{{#1}:}}
421: \newcommand{\floor}[1]{\lfloor {#1} \rfloor}
422: \newcommand{\ceiling}[1]{\lceil {#1} \rceil}
423: \newcommand{\bigfloor}[1]{\left\lfloor {#1} \right\rfloor}
424: \newcommand{\bigceiling}[1]{\left\lceil {#1} \right\rceil}
425: \newcommand{\ZZ}{\mbox{\bf Z}}
426: \newcommand\set[1]{\left\{#1\right\}}
427: \newcommand\ang[1]{\left\langle #1 \right\rangle}
428: \newcommand{\myspan}{\mbox{\rm span}}
429: \newcommand{\rank}{\mbox{\rm rank}}
430: \newcommand{\reals}{{\mathbb R}}
431: \newcommand{\nats}{{\mathbb N}}
432: \newcommand{\ints}{{\mathbb Z}}
433: %\newcommand{\bools}{{\mathbb B}}
434: \newcommand{\bools}{\{\tto,\ttl\}}
435: \newcommand{\sgn}{\mbox{\rm sign}}
436: \newcommand{\bin}[2]{(_{#2}^{#1})}
437: \newcommand{\ham}[1]{\|{#1}\|_1}
438: \newcommand{\powerset}{{\cal P}}
439: \newcommand{\wo}[1]{\mbox{\tt {#1}}}
440: \newcommand{\wordlength}{W}
441: \newcommand{\mwo}[1]{\mbox{\rm {#1}}}
442: \newcommand{\kw}[1]{{\tt {#1}}}
443: \newcommand{\ccl}[1]{\mbox{\it{#1}}}
444: \newcommand{\shift}{{\mbox{\rm shift}}}
445: \newcommand{\nand}{{\bar \wedge}}
446: \newcommand{\erq}[2]{\mbox{\rm erq}[{#1},\ {#2}]}
447: %\newcommand{\concat}{\hat{\ }}
448: %\newcommand{\concat}{\cdot}
449: \newcommand{\concat}{\,}
450: \newcommand{\polylog}{{\rm\, polylog\,}}
451: \newcommand{\AC}{$AC^0$}
452: %\setcounter{secnumdepth}{1}
453: \newcommand{\note}[1]{\marginpar{\scriptsize\sf #1}}
454: \newcommand{\paren}[1]{\left({#1}\right)}
455: \newcommand{\xlabel}[1]{\label{#1}}
456: \newcommand{\scw}{w}
457: \newcommand{\scb}{{\mbox{\sc b}}}
458: \newcommand{\scd}{d}
459: \newcommand{\scs}{{\mbox{\sc s}}}
460: \newcommand{\sck}{{\mbox{\sc k}}}
461: 
462: \title{Dynamic Ordered Sets with
463: Exponential Search Trees\footnote{This paper combines
464: results presented by the authors at the 37th FOCS 1996 \cite{And96}, 
465: the 32nd STOC 2000 \cite{AT00}, and
466: the 12th SODA 2001 \cite{AT01}}}
467: \author{Arne Andersson\\
468: Computing Science Department\\
469: Information Technology, Uppsala University\\
470: Box 311, SE - 751 05 Uppsala, Sweeden\\
471: \tt arnea@csd.uu.se http://www.csd.uu.se/$\sim$arnea
472: \and
473: Mikkel Thorup\\ 
474: AT\&T Labs--Research\\
475: Shannon Laboratory\\
476: 180 Park Avenue, Florham Park\\
477: NJ 07932, USA\\
478: \tt mthorup@research.att.com }
479: \date{\ }
480: 
481: 
482: \begin{document}
483: \maketitle
484: \begin{abstract}
485: We introduce exponential search trees as a novel
486: technique for converting static polynomial space search structures 
487: for ordered sets into fully-dynamic linear space data structures.
488: 
489: This leads to an {\em optimal\/} bound of $O(\sqrt{\log n/\log\log n})$ for 
490: searching and updating a dynamic set of $n$ integer keys in
491: linear space. Here searching an integer $y$ means
492: finding the maximum key in the set which is smaller than or equal to $y$.
493: This problem is equivalent to the standard text book problem of maintaining an
494: ordered set (see, e.g., Cormen, Leiserson, Rivest, and Stein: 
495: {\em Introduction to Algorithms}, 2nd ed., MIT Press, 2001).
496: 
497: 
498: The best previous deterministic linear space bound was $O(\log
499: n/\log\log n)$ due Fredman and Willard from STOC 1990. No better
500: deterministic search bound was known using polynomial space.
501: 
502: We also get the following worst-case linear space 
503: trade-offs between the number $n$, the word length $\wordlength$, and the 
504: maximal key $U < 2^\wordlength$: $O(\min\{\log\log n+\log n/\log\wordlength,\ 
505: \log\log n\cdot\frac{\log \log U}{\log \log \log U}\})$. These trade-offs
506: are, however, not likely to be optimal.
507: 
508: Our results are generalized to finger searching and string searching, providing
509: optimal results for both in terms of $n$.
510: \end{abstract}
511: \drop{
512: \paragraph{Categories and Subject Descriptors} 
513: E.1 [Data] DATA STRUCTURES---{\em Lists stacks, and queues}, 
514: F.2.2 [Theory of Computation] ANALYSIS OF ALGORITHMS AND PROBLEM COMPLEXITY,
515: Nonnumerical Algorithms and Problems---{\em 
516: Computations on discrete structures}
517: G.2.2 [Mathematics of Computing] DISCRETE MATHEMATICS, Graph Theory---{\em 
518: Graph algorithms}
519: }
520: 
521: \section{Introduction}
522: \subsection{The Textbook Problem}
523: Maintaining a dynamic ordered set is a fundamental textbook problem. 
524: For example, following Cormen, Leiserson, Rivest, Stein: {\em Introduction to
525: Algorithms}~\cite[Part III]{CormAlgo}, the basic operations are:
526: \begin{description}
527: \item[Search $(S,k)$] Returns a pointer to an element in $S$ with key $k$, or return a null
528: pointer if $x$ is not in $S$.
529: \item[Insert $(S,x)$] Add $x$ to $S$, here $x$ is a pointer to an element.
530: The data structure may associate information with $x$,
531: e.g., parent and child pointers in binary search trees.
532: \item[Delete $(S,x)$] Remove $x$ from $S$, here $x$ is a pointer to an element in $S$.
533: \item[Predecessor/Successor $(S,x)$] Given that $x$ points at an element in $S$,
534:  return a pointer to
535: the next smaller/larger element in $S$ (or a null pointer if no such element exists).
536: \item[Minimum/Maximum $(S)$] Return a pointer to
537: the smallest/largest element in $S$ (or a null pointer if $S$ is empty).
538: \end{description}
539: To make the ordering total, we follow the convention
540: that if two elements have the same key, the last inserted element is larger.
541: 
542: For keys that can only be accessed via comparisons, all of the above
543: operations can be supported in $O(\log n)$ time\footnote{We
544: use the convention that logarithms are base 2 unless otherwise stated. Also,
545: $n$ is the number of stored elements}, which is best
546: possible.  
547: 
548: However, on computers, integers and floating point numbers are the
549: most common ordered data types. For such data types, represented as
550: lexicographically ordered, we can apply classical non-comparison based
551: techniques such as radix sort and hashing.  Historically, we note that
552: radix sort dates back at least to 1929 \cite{Com29} and hashing dates
553: back at least to 1956 \cite{Dum56}, whereas the focus on general
554: comparison based methods only dates back to 1959 \cite{FJ59}.
555: 
556: In this paper, we consider the above basic data types of integers and
557: floating point numbers. {\em Our main result is that we can support
558: all the above operations in $O(\sqrt{\log n/\log\log n})$ worst-case
559: time, and this common bound is best possible.}
560: 
561: The lower bound follows from a result of Beame and Fich~\cite{BF99}.
562: It shows that even if we just want to support Insert and Predecessor
563: in polynomial space, one of these two operations have a worst-case
564: bound of $\Omega(\sqrt{\log n/\log\log n})$, matching our common
565: upper bound. We note that one can find better bounds and trade-offs for
566: some of the individual operations. Indeed, we will
567: support Min, Max, Predecessor, Successor, and Delete in constant time, and
568: only do Insert and Search in $\Theta(\sqrt{\log n/\log\log n})$ time.
569: 
570: It is also worth noticing that if we just want to consider an 
571: incremental dictionary with Insert and Search, then our $O(\sqrt{\log
572:   n/\log\log n})$ Search time is the best known with $n^{o(1)}$ Insert
573: time.
574: 
575: \subsection{Extending the search operation}
576: 
577: In an ordered set, it is common to consider an extended version of Search:
578: \begin{description}
579: \item[Search $(S,k)$] Returns a pointer to an element in $S$ with the largest key
580: smaller than or equal to $k$, or null if $k$ is smaller than any key
581: in $S$.
582: \end{description}
583: Thus, if the key is not there, we do not just return a null pointer.
584: It is for this extended search that we provide our $O(\sqrt{\log
585:   n/\log\log n})$ upper bound. It is also for this search operation
586: that Beame and Fich~\cite{BF99} proved their $\Omega(\sqrt{\log
587:   n/\log\log n})$ lower bound, and that was even for a single extended
588: search in a static set $S$ for any given representation in polynomial
589: space. To see that this gives a lower bound just for Insert and
590: Predecessor, we can solve the static predecessor problem
591: as follows. First we insert all the elements of $S$ to create a
592: representation of $S$. The lower bound of Beame and Fich does not care
593: about the time for this preprocessing. To search $k$, we insert an
594: element with $k$ and ask for the predecessor of this element. The
595: lower bound of Beame and Fich then asserts that the Insert and
596: Predecessor operation together takes $\Omega(\sqrt{\log n/\log\log
597:   n})$ time in the worst-case, hence that at least one of the operations
598: has a worst-case lower bound of $\Omega(\sqrt{\log n/\log\log n})$.
599: 
600: In the rest of this paper, {\em search} refers to the extended version
601: whereas the primitive version, returning null if the key is not there,
602: is referred to as a {\em look-up}.
603: 
604: 
605: We will always maintain a sorted doubly-linked list with the stored elements
606: and a distinguished head and tail. With this list we support
607: Successor, Predecessor, Minimum, and Maximum in constant time.
608: Then Insert subsumes a Search identifying the element after which the
609: key is to be inserted. Similarly, if we want to delete by a key value,
610: rather than by a pointer to an element, a Search, or look-up, identifies an
611: element with the key to be deleted, if any. 
612: 
613: To isolate the search cost from the update cost, we talk about {\em finger
614: updates}, where for Insert, we are given the element after which the
615: key is to be inserted, and for Delete, we are given the element
616: to be deleted. Then an update with a key value is implemented
617: with a Search followed by a finger update. As we shall discuss later
618: in Section \ref{ssec:intro-finger}, we will implement all finger updates
619: in constant time. However, below, we mostly discuss common upper bounds
620: for searching and updating.
621: 
622: 
623: \subsection{History}
624: 
625: 
626: At STOC'90, Fredman and Willard \cite{FW93} surpassed the
627: comparison-based lower bounds for integer sorting and searching using
628: the features available in a standard imperative
629: programming languages such as C.  Their key result was an
630: $O(\log n/\log\log n)$ time bound for deterministic dynamic searching
631: in linear space. The time bounds for dynamic searching include both
632: searching and updates. Fredman and Willard's dynamic searching immediately
633: provided them an $O(n\log n/\log\log n)$ sorting routine. They asked the
634: fundamental question: {\em how fast can we search [integers on a
635: RAM]?\/} Since then, much effort has been spent on finding the
636: inherent complexity of fundamental searching and sorting problems.
637: 
638: In this paper, we introduce exponential search trees as a novel
639: technique for converting static polynomial space search structures for
640: ordered sets into fully-dynamic linear space data structures.  Based
641: on this we get an optimal worst-case bound of $O(\sqrt{\log n/\log\log
642: n})$ for dynamic integer searching. We note that this also provides the
643: best bounds for the simpler problem of membership and look-up queries
644: if one wants updates in $n^{o(1)}$ time  \cite{HMP01}.
645: 
646: Our results also extend to optimal finger search with constant
647: finger update, and to optimal string searching. 
648: 
649: \subsection{Model of computation} 
650: Our algorithms runs on a RAM, which models what we program in
651: imperative programming languages such as C. The memory is divided into
652: addressable words of length $\wordlength$. Addresses are themselves
653: contained in words, so $\wordlength\geq \log n$.  Moreover, we have a
654: constant number of registers, each with capacity for one word. The
655: basic instructions are: conditional jumps, direct and indirect
656: addressing for loading and storing words in registers, and some
657: computational instructions, such as comparisons, addition, and
658: multiplication, for manipulating words in registers.  The space
659: complexity is the maximal memory address used, and the time complexity
660: is the number of instructions performed. All keys are assumed to be
661: integers represented as binary strings, each fitting in one word.  One
662: important feature of the RAM is that it can use keys to compute
663: addresses, as opposed to comparison-based models of computation. This
664: feature is commonly used in practice, for example in bucket or radix
665: sort.
666: 
667: The restriction to integers is not as severe as it may seem.
668: Floating point numbers, for example, are ordered correctly, simply by
669: perceiving their bit-string representation as representing an integer.
670: Another example of the power of integer ordering is fractions of
671: two one-word integers. Here we get the right ordering if we carry 
672: out the division with floating point numbers with $2\wordlength$ bits 
673: of precession, and then just perceive the result as an integer. 
674: The above examples illustrate how integer
675: ordering can capture many seemingly different orderings that 
676: we would naturally be interested in.
677: 
678: The above word model is equivalent to a restriction that one only has
679: unit cost operations for integers that are polynomial in $n$ and the
680: integers in $X$. The later formulation goes back to Kirkpatrick and
681: Reisch in 1984 \cite{KR84}. We note that if we do not somehow limit
682: the size of the unit-cost integers, we get NP$=$P unless we start
683: ruling out common instructions such as multiplication and shifts.
684: 
685: 
686: \subsection{Historical developments}
687: As mentioned above, in 1990, Fredman and Willard \cite{FW93} showed that one 
688: can do dynamic searching in $O(\log n/\log\log n)$ time.  
689: They also showed that the
690: $O(\log n/\log\log n)$ bound could be replaced by an $O(\sqrt{\log
691: n})$ bound if we allow randomization or space unbounded in terms of
692: $n$. Fredman and Willard original construction was amortized, but
693: in 1992, Willard \cite[Lemma 3.3]{Wil00} showed that
694: the update bounds can be de-amortized so as to get worst-case bounds
695: for all operations.
696: 
697: In 1996, Andersson \cite{And96} introduced
698: {\em exponential search trees\/} as a general technique reducing
699: the problem of searching a dynamic set in linear space 
700: to the problem of creating a search structure for a static
701: set in polynomial time and space. The search time for the
702: static set essentially becomes the amortized search time in
703: the dynamic set. From Fredman and Willard \cite{FW93}, he got
704: a static search structure with $O(\sqrt{\log n})$ search time, and thus
705: he obtained an $O(\sqrt{\log n})$ time bound 
706: for dynamic searching in linear space.
707: 
708: In 1999, Beame and Fich showed that $\Theta(\sqrt{\log n/\log\log n})$ is
709: the exact complexity of searching a static set using polynomial space
710: \cite{BF99}.
711: Using the above mentioned exponential search trees, this gave
712: them $\Theta(\sqrt{\log n/\log\log n})$ amortized cost
713: for dynamic searching in linear space.
714: 
715: Finally, in 2000, Andersson and Thorup \cite{AT00} developed
716: a worst-case version of exponential search trees, giving
717: an {\em optimal\/}  $O(\sqrt{\log n/\log\log n})$ worst-case
718: time bound for dynamic searching. This is the main result presented
719: in this paper.
720: 
721: \subsection{Bounds in terms of the word length and the maximal key} 
722: Besides the
723: above mentioned bounds in terms of $n$, we get 
724: the following worst-case linear space 
725: trade-offs between the number $n$, the word length $\wordlength$, and the 
726: maximal key $U < 2^\wordlength$: $O(\min\{\log\log n+\log n/\log\wordlength,\ 
727: \log\log n\cdot\frac{\log \log U}{\log \log \log U}\})$.
728: The last bound should be compared with van Emde Boas' 
729: bound of $O(\log\log U)$ \cite{vB77,vBKZ77} that requires
730: randomization (hashing) in order to achieve linear space~\cite{MN90}. We note
731: that these bounds are probably not optimal. The best
732: lower bound on searching in terms of $U$ is Beame and Fich's 
733: $\Omega(\frac{\log \log U}{\log \log \log U})$ for the static case. 
734: 
735: \subsection{AC$^0$ operations}
736: As an additional challenge, Fredman and Willard \cite{FW93} asked how
737: quickly we can search on a RAM if all the computational instructions
738: are AC$^0$ operations.  A computational instruction is an AC$^0$
739: operation if it is computable by an $\wordlength^{O(1)}$-sized constant
740: depth circuit with $O(\wordlength)$ input and output bits. In the circuit
741: we may have negation, and-gates, and or-gates with unbounded fan-in.
742: Addition, shift, and bit-wise boolean operations are all AC$^0$
743: operations. On the other hand, multiplication is not. Fredman and Willard's
744: own techniques \cite{FW93} were heavily based on multiplication, but, as 
745: shown in \cite{AMT99} they can be implemented with AC$^0$ operations if
746: we allow some non-standard operations that are not part of the usual
747: instruction set. However, here we are interested in algorithms
748: using only standard operations so that they can be implemented in
749: a standard programming language such as C.
750: 
751: Concerning searching, our $O(\sqrt{\log n/\log\log n})$ search
752: structure is strongly based on multiplication. So far, even if we
753: allow amortization and randomization, no search structure using
754: standard AC$^0$ operations has been presented using polynomial space 
755: and $o(\log n)$ time, not even
756: for the static case. Without requirements of polynomial space,
757: Andersson \cite{And95} has presented a deterministic worst-case bound
758: of $O(\sqrt{\log n})$.  In this paper, we will present a linear space
759: worst-case AC$^0$ bound of $O((\log n)^{3/4+o(1)})$, thus surpassing the
760: $O(\log n)$ bound even in this restricted case.
761: 
762: \subsection{Finger searching}\label{ssec:intro-finger}
763: By {\em finger search} we mean that we can have a ``finger'' pointing
764: at a stored key $x$ when searching for a key $y$. Here a finger is
765: just a reference returned to the user when $x$ is inserted or searched
766: for. The goal
767: is to do better if the number $q$ of stored keys between $x$ and $y$ is
768: small. Also, we have {\em finger updates}, where for deletions, one
769: has a finger on the key to be deleted, and for insertions, one
770: has a finger to the key after which the new key is to be inserted.
771: 
772: In the comparison-based model of computation Dietz and Raman
773: \cite{DR94} have provided optimal bounds, supporting finger searches
774: in $O(\log q)$ time while supporting finger updates in constant time.
775: Very recently, Brodal et al.~\cite{BrodFing} have managed to match these
776: results on a pointer machine.
777: 
778: In this paper we present optimal bounds on the RAM; namely
779: $O(\sqrt{\log q/\log\log q})$ for finger search with constant time finger
780: updates. Also, we present the first finger search bounds that are efficient
781: in terms of the absolute distance $|y-x|$ between $x$ and $y$.
782: 
783: \subsection{String searching}
784: We will also consider the case of string searching where each key may
785: be distributed over multiple words.  Strings are then ordered
786: lexicographically. One may instead be interested in variable length
787: multiple-word integers where integers with more words are considered
788: larger. However, by prefixing each integer with its length, we reduce
789: this case to lexicographic string searching.
790: 
791: Generalizing search data structures for string searching is nontrivial
792: even in the simpler comparison-based setting.  The first efficient
793: solution was presented by Mehlhorn~\cite[\S III]{Meh84}.  While the
794: classical method requires weight-balanced search structures, our
795: approach contains a direct reduction to any unweighted search
796: structure.  With inspiration from~\cite{And96,AT00,BF99,Meh84} we show
797: if the longest common prefix between a key $y$ and the stored keys has
798: $\ell$ words, we can search $y$ in $O(\ell+\sqrt{\log n/\log \log n})$
799: time, where $n$ is the current number of keys. Updates can be done
800: within the same time bound.  Assuming that we can address the stored
801: keys, our extra space bound is $O(n)$.
802: 
803: The above search bound is optimal, for consider an instance of the 1-word
804: dynamic search problem, and give all keys a common prefix of $\ell$ words.
805: To complete a search we both need to check the prefix in $O(\ell)$ time,
806: and to perform the 1-word search, which takes 
807: $\Omega(\ell+\sqrt{\log n/\log \log n})$ \cite{BF99}.
808: 
809: Note that one may think of the strings as divided into characters
810: much smaller than words. However, if we only deal with one such
811: character at the time, we are not exploiting the full power
812: of the computer at hand.
813: 
814: 
815: 
816: \subsection{Techniques and main theorems}
817: Our main technical contribution is to introduce exponential search
818: trees providing a general reduction from the problem of maintaining
819: a worst-case dynamic linear spaced structure to the simpler problem of
820: constructing static search structure in polynomial time and
821: space. For example, the polynomial construction time allows us to 
822: construct a dictionary deterministically with look-ups in constant time.
823: Thus we can avoid the use of randomized hashing in, e.g., a van Emde Boas's
824: style data structure \cite{vB77,FW93,MN90}.
825: The reduction is captured by the following theorem:
826: 
827: \begin{theorem}\label{thm:search-red} 
828: Suppose a static search structure on
829: $d$ integer keys can be constructed in $O(d^{k-1})$, $k\geq 2$,  
830: time and space so that it
831: supports searches in $S(d)$ time. We can then construct
832: a dynamic linear space search structure that with $n$ integer keys supports 
833: insert, delete, and
834: searches in time $T(n)$ where 
835: \begin{equation}\label{eq:rec}
836: T(n)\leq T(n^{1-1/k})+O(S(n)).
837: \end{equation}
838: The reduction itself uses only standard
839: AC$^0$ operations.
840: \end{theorem}
841: We then prove the following result on static data structures:
842: \begin{theorem}\label{thm:static-search} 
843: In polynomial time and space, we can construct a deterministic data structure
844: over $d$ keys supporting searches in 
845: $O(\min\{\sqrt{\log d},\log \log U,
846: 1  + \frac{\log d}{\log \wordlength}\})$ time 
847: where $\wordlength$ is the word length, and $U < 2^{\wordlength}$ is an
848: upper bound on the largest key. If we restrict ourselves to 
849: standard AC$^0$ operations, we
850: can support searches in $O((\log d)^{3/4+o(1)})$ worst-case time
851: per operation.
852: \end{theorem}
853: Above, the $\sqrt{\log d}$ and $\log\log U$ bounds were recently improved:
854: \begin{theorem}[Beame and Fich {\cite{BF99}}] \label{thm:BF99}
855: In polynomial time and space, we can construct a deterministic data structure
856: over $d$ keys supporting searches in 
857: $O(\min\{\sqrt{\log d/\log\log d},\frac{\log \log U}{\log \log \log U}\})$ 
858: time.
859: \end{theorem}
860: Applying the recursion from Theorem \ref{thm:search-red}, substituting $S(d)$
861: with (i) the two bounds in Theorem \ref{thm:BF99}, (ii) the last bound in the
862: min-expression in
863: Theorem \ref{thm:static-search}, and (iii) the AC$^0$ bound from 
864: Theorem \ref{thm:static-search}, we immediately
865: get the following four bounds:
866: \begin{corollary}\label{cor:search} 
867: There is a fully-dynamic deterministic linear space search structure
868: supporting insert, delete, and searches in worst-case time
869: \begin{equation}\label{eq:cor:search}
870: O\left(\min\left\{
871: \begin{array}{l} 
872: \sqrt{\log n/\log\log n} 
873: \\
874: \log\log n\cdot\frac{\log \log U}{\log \log \log U}
875: \\ 
876: \log\log n  + \frac{\log n}{\log \wordlength} 
877: \end{array}
878: \right\}\right)
879: \end{equation}
880: where $\wordlength$ is the word length, and $U < 2^{\wordlength}$ is
881: an upper bound on the largest key.
882: If we restrict ourselves to standard AC$^0$ operations, we
883: can support all operations in $O((\log n)^{3/4+o(1)})$ worst-case time
884: per operation.
885: \end{corollary}
886: It follows from the lower bound by
887: Beame and Fich \cite{BF99} that
888: our $O(\sqrt{\log n/\log\log n})$ bound
889: is optimal.
890: 
891: \subsubsection{Finger search}
892: A finger search version of Theorem \ref{thm:search-red} leads us
893: to the following finger search version of Corollary \ref{cor:search}: 
894: \begin{theorem}\label{thm:finger}
895: There is a fully-dynamic deterministic linear space search structure that
896: supports finger updates in constant time, and
897: given a finger to a stored key $x$, searches
898: a key $y>x$ in time
899: $$
900: O\left(\min\left\{
901: \begin{array}{l} 
902: \sqrt{\log q/\log\log q} 
903: \\
904: \log \log q\cdot \frac{\log \log (y-x)}{\log\log\log (y-x)}
905: \\ 
906: \log\log q + \frac{\log q}{\log \wordlength} 
907: \end{array}
908: \right\}\right)$$
909: where $q$ is the number of stored keys between $x$ and $y$. If we
910: restrict ourselves to AC$^0$ operations, we still get a bound
911: of $O((\log q)^{3/4+o(1)})$.
912: \end{theorem}
913: 
914: \subsubsection{String searching} We also present a general reduction
915: from string searching to 1-word searching:
916: 
917: \begin{theorem}\label{thm:string} For the dynamic string searching problem, if the longest
918:   common prefix between a key $x$ and the stored keys has $\ell$
919:   words, we can insert, delete, and search $x$ 
920:   in~$O(\ell+\sqrt{\log n/\log \log n})$
921:   time, where $n$ is the current number of keys. In addition to the
922:   stored keys themselves, our space bound is $O(n)$.
923: \end{theorem}
924: 
925: 
926: \subsection{Contents}
927: First, in Section \ref{sec:amortized}, we present a
928: simple amortized version of exponential search trees, and then
929: we de-amortize them in Section \ref{sec:worst-case}. In Section
930: \ref{sec:static} we construct the static search structures to
931: be used in the exponential search tree.
932: In Section \ref{sec:finger}, we describe the data structure
933: for finger searching. In Section \ref{sec:string}, we describe 
934: the data structure for string searching. In Section \ref{sec:other-appl}
935: we give examples of how the techniques of this paper have been applied
936: in other work. Finally, in Section \ref{sec:open-problem}, we finish
937: with an open problem.
938: 
939: 
940: \section{The main ideas and concepts in an amortized setting}\label{sec:amortized}
941: Before presenting our worst-case exponential search trees, we here
942: present a simpler amortized version from \cite{And96}, converting
943: static data structures into fully-dynamic amortized search structures.
944: The basic definitions and concepts of the amortized construction will
945: be assumed for the more technical worst-case construction.
946: 
947: An {\em exponential search
948: tree\/} is a leaf-oriented multiway search tree where the degrees of
949: the nodes decrease doubly-exponentially down the tree.  By {\em
950: leaf-oriented}, we mean that all keys are stored in the leaves of the
951: tree. Moreover, with each node, we store a {\em splitter\/}
952: for navigation: if a key arrives at a node, a local search among
953: the splitters of the children determines which child it belongs under.
954: Thus, if a child $v$ has splitter $s$ and its successor has splitter
955: $s'$, a key $y$ belongs under $v$ if $x\in [s,s')$. We require
956: that the splitter of an internal node equals the splitter
957: of its leftmost child.
958: 
959: 
960: We also maintain a doubly-linked list over the stored keys, providing
961: successor and predecessor pointers as well as maximum and minimum. A
962: search in an exponential search tree may bring us to the successor
963: of the desired key, but if the found key is to big, we just return
964: its predecessor.
965: 
966: 
967: 
968: In our exponential search trees, the local search at each internal node 
969: is performed using a static local search 
970: structure, called an {\em $S$-structure}. 
971: We assume that an $S$-structure over $d$ keys can be built 
972: in $O(d^{k-1})$ time and space and that it supports searches 
973: in $S(d)$ time. We define an exponential search tree over $n$ keys
974: recursively:
975: \begin{itemize}
976: \item The root has degree $\Theta(n^{1/k})$.
977: \item The splitters of the children of the root are stored in 
978:       a local $S$-structure with the properties stated above. 
979: \item The subtrees are exponential search trees over
980:       $\Theta(n^{1-1/k})$ keys.
981: \end{itemize}
982: It immediately follows that searches are supported in time
983: $T(n) = O\paren{S\paren{O(n^{1/k})}} + T\paren{O(n^{1-1/k})}$, which
984: is essentially the time bound we are aiming at.
985: 
986: An exponential search tree
987: over $n$ keys takes linear space. The space of 
988: the $S$-structure at a node of degree $d$ 
989: is $O\paren{d^{k-1}}$, and the total space $C(n)$ 
990: is essentially given by
991: \begin{eqnarray}
992: C(n) &=& O((n^{1/k})^{k-1}) +  n^{1/k}\cdot C(n^{1-1/k}) \nonumber \\
993:  \Rightarrow C(n) &=& O(n). \nonumber
994: \end{eqnarray}
995: The above calculation in not complete since we only recurse to
996: subproblems of size $O(n^{1-1/k})$, and then the direct solution is
997: not linear.  However, so far we are only sketching a simple amortized
998: version in order to introduce the general ideas. A rigorous argument
999: will be given for the real worst-case version (c.f. Lemma
1000: \ref{lem:linear}).
1001: 
1002: Since $O(d^{k-1})$ bounds not only the space but also the construction time
1003: for the $S$-structure at a degree $d$ node, the same argument gives
1004: that we can construct an exponential
1005: search tree over $n$ keys in linear time.
1006: 
1007: 
1008: Recall that an update is implemented as a search, as described above,
1009: followed by a finger update. A finger delete essentially just removes
1010: the leaf with the element. However, if the leaf is the first child of
1011: its parent, its splitter has to be transfered to its successor.  For a
1012: finger insert of an element $u$ with key $k$, we get the element $v$
1013: after which the key is to be inserted. We then also have to consider
1014: the successor $v'$ of $v$. Let $s$ be the splitter of $v'$. If $k<s$,
1015: we place $u$ after $v$ under the parent of $v$, and give $u$ splitter
1016: $k$. If $k\leq s$, we place $u$ before $v'$ under the parent of $v'$, 
1017: and give $u$ splitter $s$ and $v'$ its own key as splitter.
1018: 
1019: 
1020: 
1021: 
1022: 
1023: Balance is maintained in a standard fashion by global and partial
1024: rebuilding. By the weight, $|t|$, of a (sub-)tree $t$ we mean the
1025: number of leaves in $t$. By the weight, $|v|$, of a node $v$, we mean
1026: the weight of the tree rooted at $v$.  When a subtree gets too heavy,
1027: by a factor of 2, we split it in two, and if it gets too light, by a
1028: factor of 2, we join it with its neighbor. Constructing a new subtree
1029: rooted at the node $v$ takes $O(|v|)$ time.  In addition, we need to
1030: update the $S$-structure at $v$'s parent $v$, in order to reflect the
1031: adding or removing of a key in $u$'s list of child splitters.  Since
1032: $v$ has $\Theta(|v|^{1/k})$ children, the construction time for $v$'s
1033: $S$-structure is $O((|v|^{1/k})^{k-1})=O(|v|^{1-1/k})$. By definition,
1034: this time is $O(|t|)$.  We conclude that we can reconstruct the
1035: subtrees and update the parent's $S$-structure in time linear in the
1036: weight of the subtrees.
1037: 
1038: Exceeding the weight constraints requires that a constant fraction of
1039: the keys in a subtree have been inserted and deleted since the subtree
1040: was constructed with proper weight. Thus, the reconstruction cost is
1041: an amortized constant per key inserted or deleted from a tree. Since
1042: the depth of an exponential search tree is $O(\log\log n)$, the update
1043: cost, excluding the search cost for finding out were to update, is
1044: $O(\log\log n)$ amortized. This completes our sketchy description of
1045: amortized exponential search trees.
1046: 
1047: 
1048: 
1049: 
1050: \section{Worst-case exponential search trees}\label{sec:worst-case}
1051: The goal of this section is to prove the statement of 
1052: Theorem~\ref{thm:search-red}:
1053: \begin{quote}\it
1054: Suppose a static search structure on
1055: $d$ integer keys can be constructed in $O(d^{k-1})$, $k\geq 2$,  
1056: time and space so that it
1057: supports searches in $S(d)$ time. We can then construct
1058: a dynamic linear space search structure that with $n$ integer keys supports 
1059: insert, delete, and
1060: searches in time $T(n)$ where 
1061: $T(n)\leq T(n^{1-1/k})+O(S(n))$. The reduction itself uses only standard
1062: AC$^0$ operations.
1063: \end{quote}
1064: In order to get from the amortized bounds above to worst-case bounds,
1065: we need a new type of data structure.
1066: Instead of a data structure where we occasionally rebuild entire subtrees,
1067: we need a multiway tree which is something more in the style of a 
1068: standard B-tree, where
1069: balance is maintained by locally joining and splitting nodes.
1070: By locally we mean that the joining and splitting is done just by
1071: joining and splitting the children sequences.
1072: This type of data structure is for example used by Willard \cite{Wil00}
1073: to obtain a worst-case version of fusion trees.
1074: 
1075: One problem with our current definition of exponential search trees is
1076: that the criteria for when subtrees are too large or too small depend
1077: on their parents. If two subtrees are joined, the resulting subtree is
1078: larger, and according to our recursive definition, this may imply that
1079: all of the children simultaneously become too small, so they have to
1080: be joined, etc. To avoid such cascading effects of joins and
1081: splits, we redefine the exponential search tree as follows:
1082: \begin{definition}
1083: \label{def:exp}
1084: In an exponential search tree all leaves are on the same
1085: depth, and we define the height or level of a node to be the unique
1086: distance from the node to the leaves descending from it. For a non-root
1087: node $v$ at height $i>0$, the weight (number of descending leaves) is 
1088: $|v|=\Theta(n_i)$ where $n_i=\alpha^{(1+1/(k-1))^{i}}$ and $\alpha=\Theta(1)$.
1089: If the root has height $h$, its weight is $O(n_h)$.
1090: \end{definition}
1091: With the exception of the root, Definition \ref{def:exp} 
1092: follows our previous definition
1093: of exponential search trees, that is, if $v$ is a non-root node, it has
1094: $\Theta(|v|^{1/k})$ children, each of weight $\Theta(|v|^{1-1/k})$.
1095: 
1096: Our main challenge is now to rebuild $S$-structures in the background
1097: so that they remain sufficiently updated as nodes get joined and
1098: split.  In principle, this is a standard task (see e.g. \cite{WL85}).
1099: Yet it is a highly delicate puzzle which is typically either not done
1100: (e.g. Fredman and Willard  \cite{FW93} only claimed 
1101: amortized bounds for their original fusion trees), 
1102: or done with rather incomplete sketches (e.g. Willard \cite{Wil00} 
1103: only presents a 
1104: 2-page sketch of his
1105: de-amortization of fusion trees). Furthermore, our
1106: exponential search trees pose a new complication; namely that when we
1107: join or split, we have to rebuild, not only the $S$-structures of the
1108: nodes being joined or split, but also the $S$-structures of their parent.
1109: For contrast, when Willard \cite{Wil00} de-amortizes fusion trees,
1110: he actually uses the ``atomic heaps'' from \cite{FW94} as $S$-structures,
1111: and these atomic heaps support insert and delete in constant time. 
1112: Hence, when nodes get joined or split, he can just delete or insert 
1113: the splitter between them directly in the parents $S$-structure, 
1114: without having to rebuild it.
1115: 
1116: In this section, we will present a general 
1117: quotable theorem about rebuilding, thus making proper de-amortization much
1118: easier for future authors. 
1119: 
1120: \subsection{Join and split with postprocessing}\label{ssec:balance}
1121: As mentioned, we are going to deal generally with multiway trees where joins
1122: and splits cannot be completed in constant time. For the moment,
1123: our trees are only described structurally with a children list for each 
1124: non-leaf node. Then joins and splits can be done in constant time. However,
1125: after each join or split, we want to allow for some unspecified
1126: {\em postprocessing\/} before the involved nodes can participate in new 
1127: joins and splits. This postprocessing time will, for example, be used to 
1128: update parent pointers and $S$-structures.
1129: 
1130: The key issue is to schedule the postprocessing, possibly involving
1131: reconstruction of static data structures, so that we obtain good
1132: worst-case bounds. We do this by dividing each postprocessing into
1133: {\em local update steps} and ensuring that each update only uses a few
1134: local update steps at the same time as each postprocessing is given enough 
1135: steps to complete. The schedule is independent of how these update
1136: steps are performed.
1137: 
1138: To be more specific in our structural description of a tree, 
1139: let $u$ be the predecessor of $v$ in their
1140: parent's children list $C$. A {\em join\/} of $u$ and
1141: $v$ means that we append the children list of $v$ to that of $u$ so
1142: that $u$ adopts all these children from $v$. Also, we delete $v$ from
1143: $C$. Similarly, a {\em split\/} of a node $u$ at its child $w$ means
1144: that we add a new node $v$ after $u$ in the children list $C$ of $u$'s
1145: parent, that we cut the children list of $u$ just before $w$, and make
1146: the last part the children list of $v$. Structural splits and joins
1147: both take constant time and are viewed as atomic operations. In the
1148: postprocessing of a join, the resulting node is not allowed to
1149: participate in any joins or splits. In the postprocessing of a split, the
1150: resulting nodes are neither allowed to participate directly in a join
1151: or split, nor is the parent allowed to split between them.
1152: 
1153: We are now in the position to present our general theorem on 
1154: worst-case bounds for joining and
1155: splitting with postprocessing:
1156: 
1157: \begin{theorem}\label{thm:balance} 
1158: Given a number series $n_1, n_2, \ldots$, with $n_1\geq 84$, $n_{i+1} >
1159: 18 n_i$, we can schedule split and joins to maintain a multiway tree where
1160: each non-root node $v$ on height $i>0$ has weight between $n_i/4$ and $n_i$.
1161: A root node on height $h>0$ has weight at most $n_h$ and at least
1162: $2$ children. The schedule gives the following properties:
1163: 
1164: (i) When a leaf $v$ is inserted or deleted, for each node $u$ on the
1165: path from $v$ to the root 
1166: the schedule use one local update step contributing
1167: to the postprocessing of at most one join or split involving 
1168: either $u$ or a neighbor of $u$. 
1169: 
1170: (ii) For each split or join at level $i$
1171: the schedule ensures that we have $n_i/84$ local update steps 
1172: available for postprocessing, including one at the time of
1173: the split or join.
1174: 
1175: (iii) If the time of a local update step on level
1176: $i$ is bounded by $t_i=\Omega(1)$, each update is supported in
1177: $O(\sum_{i=1}^h t_i)$ time.
1178: \end{theorem}
1179: In our exponential search tree, we will have $t_i=O(1)$, but $t_i=\omega(1)$
1180: has been useful in connection with priority queues \cite{AT00}.
1181: 
1182: The above numbers ensure that a node which is neither root nor leaf
1183: has at least $(n_i/4)/n_{i-1}=18/4>4$ children. If the
1184: root node is split, a new parent root is generated implicitly.
1185: Conversely, if the root's children join to a single child, the root is
1186: deleted and the single child becomes the new root. The proof
1187: of Theorem \ref{thm:balance} is rather delicate, and deferred till
1188: later. Below we show how to apply Theorem \ref{thm:balance} in
1189: exponential search trees. As a first simple application of the schedule,
1190: we show how to maintain parents.
1191: \begin{lemma}\label{lem:parents} In Theorem \ref{thm:balance}, 
1192: the parent of any node can be computed in constant time. 
1193: \end{lemma}
1194: \begin{proof}
1195: With each node, we maintain a parent pointer, which points to
1196: the true parent, except, possibly during the postprocessing
1197: of a split or join. Split and joins are handled equivalently. 
1198: Consider the case of a join of $u$ and $v$
1199: into $v$. During the postprocessing, we will redirect all
1200: the parent pointers of the old children of $v$ to point to
1201: $u$. Meanwhile, we will have a forward pointer from $v$ to $u$ so
1202: that parent queries from any of these children can be answered
1203: in constant time, even if the child still points to $v$.
1204: 
1205: Suppose that the join is on level $i$. Then $v$ could not have more
1206: than $n_i$ children. Hence, if we redirect $84$ of their parent
1207: pointers in each local update step, we will be done the end of the
1208: postprocessing of Theorem \ref{thm:balance}. The redirections are done
1209: in a traversal of the children list, starting from the old first child
1210: of $v$. One technical detail is, however, that we may have join and
1211: split in the children sequence. Joins are not a problem, but for split
1212: we make the rule that a if we split $u'$ into $u'$ and $v'$, $v'$
1213: inherits the parent pointer of $v'$. Also, we make the split rule that
1214: if the parent pointer of $u'$ is to a node like $v$ with a forward
1215: pointer to a node like $u$ that $v$ is being joined to, we redirect
1216: the next child in the above redirection traversal from $v$. This way
1217: we make sure that the traversal of the old children list of $v$
1218: is not delayed by splits in the list.
1219: \end{proof}
1220: For our exponential search trees, we will use the postprocessing for
1221: rebuilding $S$-structures. We will still keep a high level of
1222: generality to facilitate other applications, such as, for example, 
1223: a worst-case version of the original fusion trees \cite{FW93}.
1224: \begin{corollary}\label{cor:search-balance} 
1225: Given a number series $n_0,n_1, n_2, \ldots$, with $n_0=1$, $n_1\geq 84$, 
1226: $n_{i+1} >
1227: 18 n_i$, we maintain a multiway tree where each node on height $i$ 
1228: which is neither the root nor a leaf node has weight between $n_i/4$ and 
1229: $n_i$. If an $S$-structure for a node on height $i$ 
1230: can be built in $O(n_{i-1}t_i)$ time, $t_i=\Omega(1)$, 
1231: we can maintain $S$-structures
1232: for the whole tree in $O(\sum_{i=1}^h t_i)$ time per finger update.
1233: \end{corollary}
1234: \begin{proof}
1235: In Section \ref{sec:amortized}, we described how
1236: a finger update, in constant time, translates into
1237: the insertion or deletion of a leaf. We can
1238: then apply Theorem \ref{thm:balance}.
1239: 
1240: Our basic idea is that we have an ongoing periodic rebuilding of the
1241: $S$-structure at each node $v$. A period starts by scanning the splitter
1242: list of the children of $v$ in $O(n_i/n_{i-1})$ time. It then creates a new
1243: $S$-structure in $O(n_{i-1}t_i)$ time, and finally, in constant time, it
1244: replaces the old $S$-structure with the new $S$-structure.  The whole
1245: rebuilding is divided into $n_{i-1}/160$ steps, each taking $O(t_i)$ time.
1246: 
1247: Now, every time an update contributes to a join or split postprocessing
1248: on level $i-1$, we
1249: perform one step in the rebuilding of the $S$-structure of the parent $p$, 
1250: which is on level $i$. 
1251: Then Theorem \ref{thm:balance} ascertains that we perform 
1252: $n_{i-1}/84$ steps on $S(p)$ during the postprocessing, and hence we
1253: have at least one complete rebuilding of $S(p)$ with(out) the splitter
1254: created (removed) by the split (join).
1255: 
1256: When two neighboring nodes $u$ and $v$ on level $i-1$ join,
1257: the next rebuilding of $S(u)$ will automatically include the old
1258: children of $v$. The rebuilding of $S(v)$ is continued for all updates
1259: belonging under the old $v$ until the $S(u)$ is ready to take over, but
1260: these updates will also promote the rebuilding of $S(u)$. This way we
1261: make sure that the children of $v$ and $u$ do not experience any delay
1262: in the rebuilding of their parents $S$-structure. Note that $S(u)$
1263: is completely rebuilt in $n_{i-2}/84$ steps which is much less than
1264: the $n_{i-1}$ steps we have available for the postprocessing.
1265: 
1266: During the postprocessing of the join, we may, internally, have to
1267: forward keys between $u$ and $v$. More precisely, if a key arrives at
1268: $v$ from the parents $S$-structure and $S(u)$ has been updated to take
1269: over $S(v)$, the key is sent through $S(u)$. Conversely, $S(v)$ is
1270: still in use; if a key arriving at $u$ is larger than or equal to the
1271: splitter of $v$ it is sent through $S(v)$.
1272: 
1273: The split is implemented using the same ideas: all updates for the two
1274: new neighboring nodes $u$ and $v$ promote both $S(u)$ and $S(v)$.
1275: For $S(u)$, we finish the current rebuilding over all the children 
1276: before doing a rebuild excluding the children going to $v$. By the end
1277: of the latter rebuild, $S(v)$ will also have been completed. If a key
1278: arrives at $v$ and $S(v)$ is not ready, we send it through
1279: $S(u)$. Conversely, if $S(v)$ is ready and a key arriving at $u$ is
1280: larger than or equal to the splitter of $v$, the key is sent though
1281: $S(v)$.
1282: \end{proof}
1283: Below we establish some simple technical lemmas verifying that
1284: Corollary \ref{cor:search-balance} applies
1285: to the exponential search trees from Definition \ref{def:exp}.
1286: The first lemma shows that the number sequences $n_i$ match.
1287: \begin{lemma}\label{lem:exp-bound}  
1288: With $\alpha=\max\{84^{(k-1)/k},18^{(k-1)^2/k}\}$ and
1289: $n_i=\alpha^{(1+1/(k-1))^i}$ as in Definition \ref{def:exp},
1290: $n_1\geq 84$ and $n_{i+1}/n_i\geq 18$ for $i\geq 1$.
1291: \end{lemma}
1292: \begin{proof} $n_1\geq (84^{(k-1)/k})^{1+1/(k-1)}=84$ and
1293: $n_{i+1}/n_i=n_{i+1}^{1/k}\geq n_{2}^{1/k}\geq \alpha^{(k/(k-1))^2/k}$.
1294: \end{proof}
1295: Next, we show that the $S$-structures are built fast enough.
1296: \begin{lemma}\label{lem:simple-update} 
1297: With Definition \ref{def:exp}, creating an $S$-structure 
1298: for a node $u$ on level $i$ takes $O(n_{i-1})$ time, and the total
1299: cost of a finger update is $O(\log\log n)$.
1300: \end{lemma}
1301: \begin{proof}
1302: Since $u$ has degree at most $4n_i^{1k/}$,
1303: the creation takes $O((n_i^{1/k})^{k-1})=O((n_i^{1-1/k})=O(n_{i-1})$ time.
1304: Thus, we get $t_i=O(1)$ in Corollary \ref{cor:search-balance}, corresponding
1305: to a finger update time of $O(\log\log n)$.
1306: \end{proof}
1307: Since $S(n)=\Omega(1)$, any time bound derived from Theorem
1308: \ref{thm:search-red} is $\Omega(\log\log n)$, dominating our cost of a
1309: finger update. 
1310: 
1311: Next we give a formal proof that the recursion formula of Theorem 
1312: \ref{thm:search-red} holds.
1313: \begin{lemma} 
1314: \label{lem:search-red}
1315: Assuming that the cost for searching in a node of degree~$d$ is
1316: $O(S(d))$, the search time for an $n$ key exponential search tree
1317: from Definition \ref{def:exp} is bounded 
1318: by $T(n)\leq T(n^{1-1/k})+O(S(n))$ for $n=\omega(1)$.
1319: \end{lemma}
1320: \begin{proof} 
1321: Since $n_{i-1}=n_i^{1-1/k}$ and since the degree of a
1322: level $i$ node is at most $4n_i^{1/k}$, the search time starting
1323: just below the root at level $h-1$ is bounded by $T'(n_{h-1})$ where
1324: $n_{h-1}< n$ and $T'(m)\leq T'(m^{1-1/k})+O(S(4m^{1/k}))$. 
1325: Moreover, for $m=\omega(1)$, $4m^{1/k}>m$, so $O(S(4m^{1/k}))=O(S(m))$.
1326: 
1327: The degree of the root is bounded by $n$, so the
1328: search time of the root is at most $S(n)$. Hence our
1329: total search time is bounded by $S(n)+T'(n_{h-1})
1330: =O(T(n))$. Finally, the $O$ in $O(T(n))$ is superfluous because of
1331: the $O$ in $O(S(n))$.
1332: \end{proof}
1333: Finally, recall that our original analysis, showing that exponential search
1334: trees used linear space, was not complete. Below comes the formal proof.
1335: \begin{lemma}\label{lem:linear} The exponential search trees from
1336: Definition \ref{def:exp} use linear space.
1337: \end{lemma}
1338: \begin{proof} Consider a node $v$ at height $i$. The number of keys
1339: below $v$ is at least $n_i/4$. Since $v$ has degree at most $4 n_i^{1/k}$, 
1340: the space of the $S$-structure by $v$ is 
1341: $O((4 n_i^{1/k})^{k-1})=O(n_i^{1-1/k})$. Distributing this space
1342: on the keys descending from $v$, we get  $O(n_i^{-1/k})$ space per key.
1343: 
1344: Conversely, for a given key, the space attributed to the key by
1345: its ancestors is $O(\sum_{i=0}^{h}n_i^{-1/k})=O(1)$.
1346: \end{proof}
1347: The above lemmas establish that {\bf Theorem \ref{thm:search-red} holds
1348: if we can prove Theorem \ref{thm:balance}}.
1349: 
1350: 
1351: \subsection{A game of weight balancing}\label{ssec:balance-game}
1352: In order to prove Theorem \ref{thm:balance}, we consider
1353: a game on lists of weights. In relation to Theorem \ref{thm:balance},
1354: each list represents
1355: the weights of the children of a node on some
1356: fixed level. The purpose of the game is crystallize 
1357: what is needed for balancing on each level.
1358: Later, in a bottom-up induction, we will apply the game
1359: to all levels.
1360: 
1361: First we consider only one list.
1362: 
1363: Our goal is to maintain balance, that is, for some parameter $b$,
1364: called the ``latency'', all weights should be of size $\Theta(b)$. An
1365: adversary can update an arbitrary weight, incrementing or decrement it
1366: by one.  Every time the adversary updates a weight, we get to work
1367: locally on balance. We may join neighboring weights $w_1$ and $w_2$
1368: into one $w=w_1+w_2$, or split a weight $w$ into two $w_1$ and $w_2$,
1369: $w_1+w_2=w$.
1370: 
1371: Each join or split takes $b$ steps. A join, replacing $w_1w_2$ with
1372: $w=w_1+w_2$, takes place instantly, but requires a $b$ step postprocessing. 
1373: A split, replacing $w$ with $w_1w_2$, $w_1+w_2=w$, happens
1374: at a time chosen by the advisary during the $b$ steps. The adversary
1375: must fulfill that $|w_1-w_2|\leq\Delta b$, where
1376: $\Delta$ is called the ``split error''. This should be satisfied from the
1377: split is done and until the split process are completed.
1378: 
1379: Every time a weight involved in a join or split process is updated,
1380: we get to do one step on the process. However, we may also need to
1381: work on joining or splitting of neighboring weights. More precisely, a
1382: weight is said to be {\em free\/} if it is not involved in a split or join
1383: process. In order to ensure that free weights do not get too small, we
1384: need a way of requesting that they soon be involved in a join or
1385: split process. To this end, we introduce tieing: if a free weight $v$
1386: has an involved neighbor $w$, we may {\em tie\/} $v$ to $w$, and then each
1387: update to $v$ will progress that process on $w$ by one step. 
1388: 
1389: Recall again that we are really working on a family of lists
1390: which the adversary may cut and concatenate. We note that the adversary
1391: may only do one operation at the time; either an update or a cut or a
1392: split, and for each operation, we get time to respond with an update
1393: step. Our only restriction on the adversary is that it is not allowed
1394: to cut between weights involved in a join or split process, or cut off
1395: a weight tied to such a process.
1396: 
1397: \begin{proposition}
1398: \label{lem:buckets} Let $\mu>1$. Let $b$ be the ``latency'' , and 
1399: $\Delta$ be the ``split error''. A list is ``neutral'' if
1400: all weights are strictly between $(\mu+3)b$ and
1401: $(2\mu+\Delta+9)b$. We start with neutral lists, and neutral lists
1402: can be added and removed at any time. As long as all lists have a total weight
1403: $>(\mu+3)b$, there is a protocol guaranteeing that the each weight is
1404: between $\mu b$ and $(3\mu+\Delta+14)b$, and that the total weight of
1405: any uncuttable segment of a list is at most $(5\mu+\Delta+19)b$.
1406: 
1407: In particular, for $\Delta=7$ and $\mu=21$, with start weights strictly 
1408: between $24b$ and $58b$, we guarantee 
1409: that the weights stay between $21b$ and $84b$ and that the maximum 
1410: uncuttable segment is of size at most $131b$.
1411: \end{proposition}
1412: In our application, \mtch we define $B=84b$ so the base
1413: segments of size between $\frac14 B$ and $B$, and the uncuttable
1414: segments are of size below $2B$. A list is then neutral if all weights
1415: are between $\frac{24}{84}B<\frac13 B$ and $\frac{58}{84}B>\frac23 B$.
1416: We are then given $b=\frac1{84}B$ update steps to perform a join or split,
1417: and during a split, the two new weights should differ by at most
1418: $\frac1{12}B$.
1419: 
1420: As a first step in the proof of Proposition \ref{lem:buckets}, we present
1421: the concrete protocol itself.
1422: \begin{itemize}
1423: \item[(a)] If a free weight gets up to $sb$, $s=2\mu+\Delta+9$, we 
1424: split it. (Recall that we even allow an adversary to postpone the event
1425: when the split is actually made.)
1426: \item[(b)] If a free weight $v$ gets down to $mb$, $m=\mu+3$ and has a free 
1427: neighbor $w$, we join $v$ and $w$, untieing $w$ from any 
1428: other neighbor.
1429: \item[(c)] If a free weight $v$ gets down to $mb$ and
1430: has no free neighbors, we tie it to any one of its neighbors. If
1431: $v$ later gets back up above $mb$, it is untied again.
1432: \item[(d)] When we finish a join postprocessing, if the resulting weight is
1433: $\geq sb$, we immediately split it. If a neighbor was tied
1434: to the joined node, the tie is transfered to the nearest node resulting
1435: from the split. 
1436: 
1437: If the weight $v$ resulting from the join is $<sb$ and $v$ is tied
1438: by a neighbor, we join with the neighbor that tied $v$ first.
1439: \item[(e)] At the end of a split postprocessing, if any of the
1440: resulting nodes are tied by a neighbor, it joins with that
1441: neighbor. Note here that since resulting nodes
1442: are not tied to each other, there cannot be a conflict.
1443: \end{itemize}
1444: Note that our protocol is independent of legal cuts and concatenations
1445: by the adversary, except in (c) which requires that a free weight
1446: getting down to $(\mu+3)b$ has at least one neighbor. This is, however,
1447: ensured by the condition from Proposition \ref{lem:buckets} that
1448: each list has total weight strictly larger than $(\mu + 3) b$.
1449: \begin{lemma}\label{lem:nodesize}\ 
1450: \begin{itemize}
1451: \item[(i)] Each free weight is between $\mu b$ and $sb=(2\mu+\Delta+9)b$.
1452: \item[(ii)] The weight in a join process is between 
1453: $(m+\mu-1)b=(2\mu+2)b>mb$
1454: and $(s+m+1)b=(3\mu+\Delta+13)b>sb$.
1455: \item[(iii)] In a split process, the total weight is at most $(3\mu+\Delta+14))b$ and the split weights are between
1456: $((s-1-\Delta)/2) b=(\mu+4)b>mb$ and $((s+m+2+\Delta)/2) b
1457: =(1\mu+\Delta+8)b<sb$.
1458: \end{itemize}
1459: \end{lemma}
1460: \begin{proof} First we prove some simple claims.
1461: \begin{claim}
1462: If (i), (ii), and (iii) are true when a join process starts, 
1463: then (ii) will remain satisfied for that join process.
1464: \end{claim}
1465: \begin{subproof}
1466: For the upper bound note that when the join is started, none of
1467: the involved weights can be above $sb$, for then we would have split
1468: it. Also, a join has to be initiated by a weight of size at most $mb$, so
1469: when we start the total weight is at most $(s+m)b$, and during
1470: the postprocessing, it can increase by at most $b$.
1471: 
1472: For the lower bound, both weights have to be at least
1473: $\mu b$. Also, the join is either initiated as in (b) by a weight
1474: of size $mb$, or by a tied weight coming out from a join or split,
1475: which by (ii) and (iii) is of size at least $mb$, so we start with a total
1476: of at least $(\mu+m)b$, and we loose at most $b$ in the postprocessing.
1477: \end{subproof}
1478: \begin{claim}
1479: If (i), (ii), and (iii) are true when a split process starts, 
1480: then (iii) will remain satisfied for that split process.
1481: \end{claim}
1482: \begin{subproof}
1483: For the lower bound, we know that a split is only initiated for a weight
1484: of size at least $sb$. Also, during the process, we can loose at most
1485: $b$, and since the maximal difference between the two weights is
1486: $\Delta b$, the smaller is of size at least $(s-1-\Delta)/2 b$.
1487: 
1488: For the upper bound, the maximal weight we can start with is one coming
1489: out from a join, which by (ii) is at most
1490: $(s+m+1)b$. We can gain at most $b$ during the split processing, so
1491: the larger weight is at most $((s+m+2+\Delta)/2)b$.
1492: \end{subproof}
1493: 
1494: We will now complete the proof of Lemma~\ref{lem:nodesize}
1495: by showing that there
1496: cannot be a first violation of (i) given that (ii) and (iii) have not
1497: already been violated. The only way we can possibly get a weight
1498: above $sb$ is one coming out from a join as in (ii), but then
1499: by (d) it is immediately split, so it doesn't become free.
1500: 
1501: To show by contradiction that we cannot get a weight below $\mu b$, 
1502: let $w$ the first weight getting down
1503: below $\mu b$ keys. When $w$ was originally created by
1504: (ii)  and (iii), it was of size $>mb$, so
1505: to get down to $\mu b$, there must have been a last time where it
1506: got down to $m b$. It then tied itself to an involved neighboring weight
1507: $w'$. If $w'$ is involved in a split, we know that when $w'$ is done, the
1508: half nearest $w$ will immediately start joining with $w$ as in (e). 
1509: However, if $w'$ is involved
1510: in a join, when done, the resulting weight may start joining with a 
1511: weight $w''$ on the
1512: other side. In that case, however, $w$ is the first weight to tie to
1513: the new join. Hence, when the new join is done, either $w$ starts joining
1514: with the result, or the result get split and then $w$ will join with
1515: the nearest weight coming out from the split. In the worst case, $w$ will
1516: have to wait for two joins and one split to complete before it
1517: gets joined, and hence it can loose at most $3b=(m-\mu)b$ while waiting
1518: to get joined.
1519: \end{proof}
1520: 
1521: \paragraph{Proof of Proposition \ref{lem:buckets}}
1522: By Lemma \ref{lem:nodesize}, all weights
1523: remain between $\mu b$ and $(3\mu+\Delta+13)b$.
1524: Concerning the maximal size of an uncuttable segment,
1525: the maximal total weight involved in split or join is
1526: $(m+s+1)b$, and by (b)we can have a weight of size at most $mb$ tied
1527: from either side, adding up to a total of
1528: $(3m+s+1)b=(5\mu+\Delta+19)b$. 
1529: 
1530: 
1531: \subsection{Applying the protocol}\label{ssec:apply-prot}
1532: We now want to apply our protocol in order to prove Theorem \ref{thm:balance}:
1533: \begin{quote}\em
1534: Given a number series $n_1, n_2, \ldots$, with $n_1\geq 84$, $n_{i+1} >
1535: 18 n_i$, we can schedule split and joins to maintain a multiway tree where
1536: each non-root node $v$ on height $i>0$ has weight at between $n_i/4$ and $n_i$.
1537: A root node on height $h>0$ has weight at most $n_h$ and at least
1538: $2$ children. The schedule gives the following properties:
1539: 
1540: (i) When a leaf $v$ is inserted or deleted, for each node $u$ on the
1541: path from $v$ to the root 
1542: the schedule use one local update step contributing
1543: to the postprocessing of at most one join or split involving 
1544: either $u$ or a neighbor of $u$. 
1545: 
1546: (ii) For each split or join at level $i$
1547: the schedule ensures that we have $n_i/84$ local update steps 
1548: available for postprocessing.
1549: 
1550: (iii) If the time of a local update step on level
1551: $i$ is bounded by $t_i=\Omega(1)$, each update is supported in
1552: $O(\sum_{i=1}^h t_i)$ time.
1553: \end{quote}
1554: For each level $i<h$, the nodes are partitioned in children lists of nodes
1555: on level $i+1$. We maintain these lists using the scheduling of Proposition
1556: \ref{lem:buckets}, with latency $b_i=n_i/84$ and split error $\Delta=7$. With
1557: $\mu=21$, this will give weights between $21 b$ and $84b$, as
1558: required. We need to ensure that the children list of a node
1559: on level $i$ can be cut so that the halves differ by at most
1560: $\Delta b_i$. For $i=1$, this is trivial, in that the children list
1561: is just a list of leaves that can be cut anywhere, that is,
1562: we are OK even with $\Delta=1$. For $i>1$, inductively,
1563: we may assume that we have the required difference of $\Delta b_{i-1}$ on
1564: level below, and then, using Proposition \ref{lem:buckets}, we
1565: can cut the list on level $i$ with a difference of $131 b_{i-1}$. However,
1566: $b_i\geq 18 b_{i-1}$, so $131 b_{i-1}\leq 7 b_i$, as required.
1567: 
1568: 
1569: Having dealt with each individual level, three unresolved problems remain:
1570: \begin{itemize}
1571: \item How do we for splits in constant time find a good place to cut
1572: the children list?
1573: \item How does the protocol apply as the height of the tree changes?
1574: \item How do we actually find the nodes on the path from the leaf $v$ to the
1575: root?
1576: \end{itemize}
1577: \paragraph{Splitting in constant time}
1578: For each node $v$ on level $i$, our goal is to maintain a good cut child 
1579: in the sense that when cutting at that child, the lists will not differ 
1580: by more than $\Delta b_i$. We will always maintain the 
1581: sum of the weights of
1582: the children preceding the cut child, and comparing that with the weight
1583: of $v$ tells us if it is at good balance. If an update makes the preceding 
1584: weight to large, we move to the next possible cut child to the right,
1585: and conversely, if it gets to small, we move the cut child to the left. 
1586: A possible cut is always at most 4 children away, so the above
1587: shifts only take constant time. Similarly, if the cut child stops being
1588: cuttable, we move in the direction that gives us the best balance.      
1589: 
1590: When a new list is created by a join or a split, we need to find a new
1591: good cut child. To our advantage, we know that we have at least
1592: $b_i$ update steps before the cut child is needed. We can therefore
1593: start by making the cut child the rightmost child, and every time
1594: we receive an update step for the join, we move to the right, stopping
1595: when we are in balance. Since the children list is of length 
1596: $O(n_i/n_{i-1})$,  we only need to move a constant number of children to 
1597: the right in each update step in order to ensure balance before the 
1598: postprocessing is ended. 
1599: 
1600: 
1601: 
1602: \paragraph{Changing the height}
1603: A minimal tree has a root on height $1$, possibly with $0$
1604: children.  If the root is on height $h$, we only apply the 
1605: protocol when it has weight at least $21b_h$, splitting
1606: it when the protocol tells us to do so. Note that there is no
1607: cascading effect, for before the split, the root
1608: has weight at most $84b_h$, and this is the weight 
1609: of the new root at height $h+1$. However $b_h\leq b_{h+1}/18$, so it 
1610: will take many updates before the new root reaches the 
1611: weight~$21 b_{i+1}$. The $S$-structure and pointers of the new root
1612: are created during the postprocessing of the split of the old
1613: root. Conversely, we only loose a root at height $h+1$ when
1614: it has two children that get joined into one child. The 
1615: cleaning up after the old root, i.e.\ the removal of its $S$-structure
1616: and a constant number of pointers, is done in the postprocessing
1617: of the join of its children. We note that the new
1618: root starts with weight at least $21 b_h$, so it has at least
1619: $21 b_h/84 b_{h-1}\geq 18/4>4$ children. Hence it will survive
1620: long enough to pay for its construction.
1621: 
1622: \paragraph{Finding the nodes on the path from the leaf $v$ to the root}
1623: The obvious way to find the nodes on the path from the leaf $v$ to the
1624: root is to use parent pointers, which according to Lemma
1625: \ref{lem:parents} can be computed in constant time. Thus, we can prove
1626: Theorem \ref{thm:balance} from Lemma \ref{lem:parents}. The only
1627: problem is that we used the schedule of Theorem \ref{thm:balance} to
1628: prove Lemma \ref{lem:parents}.  To break the circle, consider the
1629: first time the statement of Theorem \ref{thm:balance} or of Lemma
1630: \ref{lem:parents} is violated. If the first mistake is a mistaken
1631: parent computation, then we know that the scheduling and weight
1632: balancing of Theorem \ref{thm:balance} has not yet been violated, but
1633: then our proof of Lemma \ref{lem:parents} based on Theorem
1634: \ref{thm:balance} is valid, contradicting the mistaken parent
1635: computation. Conversely, if the first mistake is in Theorem
1636: \ref{thm:balance}, we know that all parents computed so far were
1637: correct, hence that our proof of Theorem \ref{thm:balance} is
1638: correct. Thus there cannot be a first mistake, so {\bf we conclude
1639: that both Theorem \ref{thm:balance} and Lemma \ref{lem:parents} are
1640: correct}. 
1641: 
1642: 
1643: %------------------------------------
1644: 
1645: \section{Static search structures}\label{sec:static}
1646: 
1647: In this section, we will prove Theorem~\ref{thm:static-search}:
1648: \begin{quote}\it
1649: In polynomial time and space, we can construct a deterministic data structure
1650: over $d$ keys supporting searches in 
1651: $O(\min\{\sqrt{\log d},\log \log U,
1652: 1  + \frac{\log d}{\log \wordlength}\})$ time 
1653: where $\wordlength$ is the word length, and $U < 2^{\wordlength}$ is an
1654: upper bound on the largest key. If we restrict ourselves to 
1655: standard AC$^0$ operations, we
1656: can support searches in $O((\log d)^{3/4+o(1)})$ worst-case time
1657: per operation.
1658: \end{quote}
1659: To get the final bounds in Corollary~\ref{cor:search}, 
1660: we actually need to improve the first bound in the min-expression to
1661: $O(\sqrt{\log n/\log\log n})$ and the second bound 
1662: to $O(\log\log U/\log\log\log U)$.
1663: However, the improvement is by Beame and Fich \cite{BF99}. 
1664: We present our bounds here
1665: because (i) they are simpler (ii) the improvement by Beame and Fich
1666: is based on our results.
1667: 
1668: 
1669: \subsection{An improvement of fusion trees}
1670: 
1671: \noindent
1672: Using our terminology,
1673: the central part of the fusion tree is a 
1674: static data structure with the following properties:
1675: 
1676: \begin{lemma} (Fredman and Willard)
1677: \label{lem:FW}
1678: For any $d$, $d = O\paren{\wordlength^{1/6}}$, 
1679: A static data structure containing $d$ keys
1680: can be constructed in $O\paren{d^4}$ time and space, 
1681: such that it supports neighbor queries 
1682: in~$O(1)$ worst-case time.
1683: \end{lemma}
1684: 
1685: Fredman and Willard used this
1686: static data structure to implement a B-tree 
1687: where only the upper levels
1688: in the tree contain B-tree nodes, all having the same degree (within 
1689: a constant factor).
1690: At the lower levels, traditional (i.e. comparison-based)
1691: weight-balanced trees were used.
1692: The amortized cost of searches and updates
1693: is $O(\log n/\log d +\log d)$
1694: for any $d = O\paren{\wordlength^{1/6}}$.
1695: The first term corresponds to the
1696: number of B-tree levels and the
1697: second term corresponds to the height of the weight-balanced trees.
1698: 
1699: Using an exponential search tree instead of the Fredman/Willard structure, 
1700: we avoid the
1701: need for weight-balanced trees at the bottom at the same
1702: time as we improve the complexity for large word sizes.
1703: 
1704: \begin{lemma}
1705: \label{lem:FWgen}
1706: A static data structure containing $d$ keys
1707: can be constructed in $O\paren{d^4}$ time and space, 
1708: such that it supports neighbor queries 
1709: in~$O\paren{\frac{\log d}{\log \wordlength}+1}$ worst-case time.
1710: \end{lemma}
1711: 
1712: \begin{proof}
1713: We just construct a static B-tree where each
1714: node has the largest possible degree according to Lemma \ref{lem:FW}.
1715: That is, it has a degree of $\min\paren{d,\wordlength^{1/6}}$.
1716: This tree satisfies the conditions of the lemma.
1717: \end{proof}
1718: 
1719: \begin{corollary}
1720: \label{cor:FWpart}
1721: There is a data structure occupying linear
1722: space for which the
1723: worst-case cost of a search and update is
1724: $O\paren{\frac{\log n}{\log \wordlength} + \log\log n}$
1725: \end{corollary}
1726: 
1727: \begin{proof}
1728: Let $T(n)$ be the worst-case cost.
1729: Combining Theorem \ref{thm:search-red} and 
1730: Lemma~\ref{lem:FWgen} gives that
1731: $$
1732: T(n) = O\paren{\frac{\log n}{\log \wordlength} + 1 + T\paren{n^{4/5}}}.
1733: $$
1734: \end{proof}
1735: 
1736: \subsection{Tries and perfect hashing}
1737: \label{sec:trie}
1738: 
1739: \noindent
1740: In a binary trie, a node at depth $i$
1741: corresponds to an $i$-bit prefix of one (or more) of the keys stored in the trie. 
1742: Suppose we could access a node by its prefix in constant time by means of a
1743: hash table, i.e. without traversing the path down to the node.
1744: Then, we could find a key~$x$, or $x$'s nearest neighbor, 
1745: in~$O(\log \wordlength)$ time by a binary search
1746: for the node corresponding to~$x$'s longest matching prefix.
1747: At each step of the binary search, we look in the hash table
1748: for the node corresponding to
1749: a prefix of $x$; if the node is there we try with a longer prefix,
1750: otherwise we try with a shorter one. 
1751: 
1752: The idea of a binary search for a matching prefix 
1753: is the basic principle of
1754: the van Emde Boas tree~\cite{vB77,vBKZ77,WillLog}.
1755: However, a van Emde Boas tree is not just a plain binary trie
1756: represented as above. One problem is the space requirements; 
1757: a plain binary trie storing $d$ keys may contain as much as $\Theta(d\wordlength)$ nodes.
1758: In a van Emde Boas tree, the number of nodes is decreased to $O(d)$ by
1759: careful optimization.
1760: 
1761: In our application $\Theta(d\wordlength)$ nodes can be allowed. Therefore,
1762: to keep things simple,
1763: we use a plain binary trie.
1764: 
1765: \begin{lemma}
1766: \label{lem:vEBgen}
1767: A static data structure containing $d$ keys
1768: and supporting neighbor queries 
1769: in~$O(\log \wordlength)$ worst-case time
1770: can be constructed in $O\paren{d^4}$ time and space.
1771: The implementation can be done without division.
1772: \end{lemma}
1773: 
1774: \begin{proof}
1775: We study two cases.
1776: 
1777: Case 1: \hbox{$\wordlength > d^{1/3}$.} Lemma \ref{lem:FWgen} gives constant query cost.
1778: 
1779: Case 2: \hbox{$\wordlength \leq d^{1/3}$.}
1780: In $O(d\wordlength)= o(d^2)$ time and space we construct a binary trie  
1781: of height~$\wordlength$ containing all $d$ keys. 
1782: Each key is stored at the bottom of a path of length $\wordlength$ and the keys
1783: are linked together. In order to support
1784: neighbor queries, each unary node 
1785: contains a neighbor pointer to the next (or previous) leaf
1786: according to the inorder traversal.
1787: 
1788: To allow fast access to
1789: an arbitrary node, we store all nodes in a perfect hash table such that
1790: each node of depth $i$ is represented by the $i$ bits on the path down to the node.
1791: Since the paths are of different length, we 
1792: use $\wordlength$ hash tables, one for each path length. Each hash table contains 
1793: at most~$d$ nodes.
1794: The algorithm by Fredman, Komlos, and
1795: Szemeredi~\cite{FredStor} constructs a hash table of $d$ keys in $O(d^3 \wordlength)$ time.
1796: The algorithm uses division, this can be avoided by
1797: simulating each division in $O(\wordlength)$ time.
1798: With this extra cost,
1799: and since we use $\wordlength$ tables, the total construction time is $O\paren{d^3 \wordlength^3}= O(d^4)$
1800: while the space is $O(d\wordlength)= o(d^2)$.
1801: 
1802: With this data structure, we can search for a key $x$ in $O(\log \wordlength)$ time by 
1803: a binary search for the
1804: node corresponding to $x$'s longest matching prefix. 
1805: This search either ends at the bottom of the trie or at a unary node,
1806: from which we find the closest neighboring leaf by following the 
1807: node's neighbor pointer.
1808: 
1809: During a search, evaluation of the hash function
1810: requires integer division. However, as pointed
1811: out by Knuth~\cite{Kn3}, division with some precomputed constant $p$ may
1812: essentially be replaced by multiplication with $1/p$.
1813: Having computed $r= \floor{2^\wordlength/p}$ once in $O(\wordlength)$ time,
1814: we can compute $x \ \idiv\ p$ as $\floor{xr / 2^\wordlength}$
1815: where the last division is just a right shift $\wordlength$ positions. 
1816: Since $\floor{x/p}-1 < \floor{xr / 2^\wordlength} \leq \floor{x/p}$ we can compute the
1817: correct value of $x \ \idiv\ p$ by an additional test.
1818: Once we can compute \idiv, we can also compute \mod.
1819: \end{proof}
1820: 
1821: 
1822: An alternative method for perfect hashing without division is the one
1823: recently developed by Raman~\cite{Ram96}. Not only does this
1824: algorithm avoid division, it is also asymptotically faster, $O(d^2 \wordlength)$.
1825: 
1826: \begin{corollary}
1827: \label{cor:vEBpart}
1828: There is a data structure occupying linear
1829: space for which the
1830: worst-case cost of a search and the amortized
1831: cost of an update is
1832: $
1833: O\paren{\log \wordlength\log\log n}.
1834: $
1835: \end{corollary}
1836: \begin{proof}
1837: Let $T(n)$ be the worst-case search cost.
1838: Combining Lemmas \ref{thm:search-red} and \ref{lem:vEBgen}
1839: gives 
1840: $
1841: T(n) = O\paren{\log \wordlength} + T\paren{n^{4/5}}. 
1842: $
1843: \end{proof}
1844: 
1845: 
1846: \subsection{Finishing the proof of Theorem \ref{thm:static-search}}
1847: 
1848: \noindent
1849: If we combine Lemmas \ref{lem:FWgen} 
1850: and \ref{lem:vEBgen}, we can in polynomial time construct
1851: a dictionary over $d$ keys supporting searches in
1852: time $S(d)$, where
1853: \begin{equation}
1854: \label{eq:totrec}
1855: S(n) = O\paren{\min\paren{
1856: % \begin{array}{l}
1857: 1+\frac{\log n}{\log \wordlength}, \log \wordlength
1858: % \end{array}
1859: }}
1860: \end{equation}
1861: Furthermore, balancing the two parts of the min-expression gives
1862: $$
1863: S(n) = O\paren{\sqrt{\log n}}.
1864: $$
1865: To get AC$^0$ bound in Theorem \ref{thm:static-search}, we 
1866: combine some known results. From Andersson's packed B-trees \cite{And95},
1867: it follows that if in polynomial time and space, we build a static 
1868: AC$^0$ dictionary with membership queries in time $t$, then in 
1869: polynomial time and space, we can build a static search structure
1870: with operation time $O(\min_i\{it+\log n/i\})$. In addition, 
1871: Brodnik et.al. \cite{BMM97} have
1872: shown that such a static dictionary, using only standard AC$^0$ operations,
1873: can be built with membership queries in time $t=O((\log n)^{1/2+o(1)})$.
1874: We get the desired static search time by setting 
1875: $i=O((\log n)^{1/4+o(1)})$. {\bf This completes the
1876: proof of Theorem \ref{thm:static-search}, hence of Corollary \ref{cor:search}}.
1877: 
1878: \subsection{Two additional notes on searching}
1879: 
1880: \noindent
1881: Firstly, we give the first 
1882: deterministic polynomial-time (in $n$)
1883: algorithm for constructing a linear space
1884: static dictionary with $O(1)$ worst-case
1885: access cost (cf. perfect hashing).
1886: 
1887: As mentioned earlier, a linear space data structure that 
1888: supports member queries
1889: (neighbor queries are not supported) 
1890: in constant time can be constructed at a worst-case cost $O\paren{n^2 \wordlength}$
1891: without division~\cite{Ram96}. 
1892: We show that the dependency of word size can be removed.
1893: 
1894: \begin{proposition}
1895: \label{obs:hash}
1896: A linear space static data structure supporting member queries at a worst
1897: case cost of $O(1)$ can be constructed 
1898: in $O\paren{n^{2+\epsilon}}$ worst-case time.
1899: Both construction and
1900: searching can be done without division.
1901: \end{proposition}
1902: 
1903: \begin{proof}
1904: W.l.o.g we assume that $\epsilon < 1/6$.
1905: 
1906: Since Raman has shown that a perfect hash
1907: function can be constructed in $O\paren{n^2 \wordlength}$ time without 
1908: division)~\cite{Ram96}, we are done
1909: for $n \geq \wordlength^{1/\epsilon}$.
1910: 
1911: If, on the other hand, $n < \wordlength^{1/\epsilon}$, we construct a static tree
1912: of fusion tree nodes with degree $O\paren{n^{1/3}}$.
1913: This degree is possible since $\epsilon < 1/6$.
1914: The height of this tree is $O(1)$, the cost of constructing a node
1915: is $O\paren{n^{4/3}}$ and the total number of nodes is $O\paren{n^{2/3}}$.
1916: Thus, the total construction cost for the tree is $O\paren{n^2}$.
1917: 
1918: It remains to show that the space taken by the fusion tree nodes
1919: is $O(n)$.
1920: According to Fredman and Willard, a fusion tree node
1921: of degree $d$ requires $\Theta\paren{d^2}$ space. This space 
1922: is occupied by a lookup table where each entry contains a 
1923: rank between $0$ and $d$. 
1924: A space of $\Theta\paren{d^2}$ is small enough for the original fusion tree
1925: as well as for our exponential search tree. However, in order to
1926: prove this proposition, we need to reduce the space taken by a
1927: fusion tree node from $\Theta\paren{d^2}$ to $\Theta\paren{d}$.
1928: Fortunately, this reduction is straightforward. 
1929: We note that a number between $0$ and $d$
1930: can be stored in $\log d$ bits. Thus, since $d < \wordlength^{1/6}$, the total 
1931: number of bits occupied by the lookup table 
1932: is $O\paren{d^2 \log d} = O(\wordlength)$. This packing of numbers is done
1933: cost efficiently by standard techniques. 
1934: 
1935: We conclude that
1936: instead of $\Theta\paren{d^2}$, 
1937: the space taken by the lookup table in a fusion tree node
1938: is $O(1)$ ($O(d)$ would have been good enough).
1939: Therefore, the space occupied by a fusion tree node can be made linear in
1940: its degree.
1941: \end{proof}
1942: 
1943: Secondly, we show how to adapt our data structure 
1944: to certain input distribution.
1945: 
1946: In some applications, we may assume that
1947: the input distribution is favorable. These kind
1948: of assumptions may lead to a number of heuristic
1949: algorithms and data structures whose analysis
1950: are based on probabilistic methods. Typically,
1951: the input keys may be assumed to be generated
1952: as independent stochastic variables from some
1953: (known or unknown) distribution; the goal is
1954: to find an algorithm with a good expected behavior.
1955: For these purposes, a deterministic algorithm is not
1956: needed.
1957: 
1958: However, instead of modeling input as the result
1959: of a stochastic process, we may characterize its
1960: properties in terms of a {\em measure}. 
1961: Attention is then moved from the process of generating
1962: data to the properties of the data itself. In this
1963: context, it makes sense to use a deterministic 
1964: algorithm; given the value of a certain measure
1965: the algorithm has a guaranteed cost.
1966: 
1967: We give one example of how to adapt our data structure according
1968: to a natural measure. 
1969: An indication of how ``hard'' it is to search for a key
1970: is how large part of it must be read in order to distinguish it from
1971: the other keys. We say that this part is the key's {\em distinguishing
1972: prefix}. (In Section \ref{sec:trie} we used the term longest
1973: matching prefix for essentially the same entity.)
1974: For $\wordlength$-bit keys, the longest possible distinguishing prefix
1975: is of length $\wordlength$. 
1976: Typically, if the input is nicely distributed,
1977: the average length of the distinguishing prefixes is $O(\log n)$.
1978: 
1979: As stated in Proposition~\ref{obs:adapt}, we can search faster when a
1980: key has a short distinguishing prefix.
1981: 
1982: \begin{proposition}
1983: \label{obs:adapt}
1984: There exist a linear-space 
1985: data structure for which the worst-case cost of a search and
1986: the amortized cost of an update is
1987: $O(\log b \log\log n)$ where $b \leq \wordlength$ is the length of the query key's
1988: distinguishing prefix, i.e. the prefix that needs to be inspected
1989: in order to distinguish it from each of the other stored keys.
1990: \end{proposition}
1991: 
1992: \begin{proof}
1993: We use exactly the same data structure as in
1994: Corollary~\ref{cor:vEBpart}, with the same restructuring cost of
1995: $O(\log\log n)$ per update.  The only difference is that we change the
1996: search algorithm from the proof of Lemma~\ref{lem:vEBgen}.  Applying
1997: an idea of Chen and Reif~\cite{ChenUsin}, we replace the binary search
1998: for the longest matching (distinguishing) prefix by an
1999: exponential-and-binary search. Then, at each node in the exponential
2000: search tree, the search cost will decrease from $O(\log \wordlength)$
2001: to $O(\log b)$ for a key with a distinguishing prefix of length~$b$.
2002: \end{proof}
2003: 
2004: 
2005: \section{Finger search and finger updates}
2006: \label{sec:finger}
2007: Recall that we have a finger pointing at a key $x$ while searching for 
2008: another key $y$, and let $q$ be the number of keys between $x$ and $y$.
2009: W.l.o.g. we assume $y>x$. In its traditional formulation,
2010: the idea of finger search is that we should
2011: be able to find $y$ quickly if $q$ is small. 
2012: Here, we also consider
2013: another possibility: the search should be fast if $y-x$ is small.
2014: Compared with the data structure for plain searching, we need
2015: some modifications to support finger search and updates efficiently.
2016: The overall goal of this section is to prove
2017: the statement of 
2018: Theorem~\ref{thm:finger}:
2019: \begin{quote}\it
2020: There is a fully-dynamic deterministic linear space search structure that
2021: supports finger updates in constant time, and
2022: given a finger to a stored key $x$, searches
2023: a key $y>x$ in time
2024: $$
2025: O\left(\min\left\{
2026: \begin{array}{l} 
2027: \sqrt{\log q/\log\log q} 
2028: \\
2029: \log \log q\cdot \frac{\log \log (y-x)}{\log\log\log (y-x)}
2030: \\ 
2031: \log\log q + \frac{\log q}{\log \wordlength} 
2032: \end{array}
2033: \right\}\right)$$
2034: where $q$ is the number of stored keys between $x$ and $y$. If we
2035: restrict ourselves to AC$^0$ operations, we still get a bound
2036: of $O((\log q)^{3/4+o(1)})$.
2037: \end{quote}
2038: Below, we will first show how to reduce the cost of finger updates 
2039: from the $O(\log\log n)$ in the last section to a constant. This
2040: will then be combined with efficient static finger search structures.
2041: 
2042: 
2043: \subsection{Constant time finger update}
2044: In this section, we will generally show how to reduce the finger
2045: update time of $O(\log\log n)$ from Lemma~\ref{lem:simple-update} to
2046: a constant. The $O(\log\log n)$ bound stems from the fact when we insert
2047: or delete a leaf, we use 
2048: a local update step for each level above the leaf. Now, however, we
2049: only want to use a constant number of local update steps in connection
2050: with each leaf update. The price is that we have
2051: less local update steps available for the postprocessing of join and splits. 
2052: More precisely, we will prove the following
2053: analogue to the general balancing in Theorem
2054: \ref{thm:balance}:
2055: \begin{theorem}\label{thm:finger-balance} 
2056: Given a number series $n_1, n_2, \ldots$, with $n_1\geq 84$, $18 n_i< n_{i+1} <
2057: n_i^2$ for $i\geq 1$, 
2058: we can schedule split and joins to maintain a multiway tree where
2059: each non-root node $v$ on height $i>0$ has weight at between $n_i/4$ and $n_i$.
2060: A root node on height $h>0$ has weight at most $n_h$ and at least
2061: $2$ children. The schedule gives the following properties:
2062: 
2063: (i) When a leaf $v$ is inserted or deleted, the schedule
2064: uses a constant number of local update steps. The additional
2065: time used by the schedule is constant.
2066: 
2067: (ii) For each split or join at level $i>1$
2068: the schedule ensures that we have at least $\sqrt{n_i}$ local update steps 
2069: available for postprocessing, including one in connection with
2070: the split or join itself. For level $1$, we have $n_1$ local updates
2071: for the postprocessing.
2072: \end{theorem}
2073: As we shall see later, the $\sqrt{n_i}$ local update steps suffice for
2074: the maintenance of $S$-structures. As for the Theorem \ref{thm:balance},
2075: we have 
2076: \begin{lemma}\label{lem:finger-parents} In Theorem \ref{thm:finger-balance}, 
2077: the parent of any node can be computed in constant time. 
2078: \end{lemma}
2079: \begin{proof} We use exactly the same construction as for 
2080: Lemma \ref{lem:parents}.  The critical point is that we for
2081: the postprocessing have a number of updates which is the proportional
2082: to the number of children of a node. This is trivially the case for
2083: level $1$, and for higher levels $i$, the number of children is
2084: at most $n_i/(n_{i-1}/4)=O(\sqrt{n_i})$.
2085: \end{proof}
2086: As in the proof of Theorem \ref{thm:balance}, we will actually use
2087: the parents of Lemma \ref{lem:finger-parents} in the proof of
2088: Theorem \ref{thm:finger-balance}. As argued at the end of
2089: Section \ref{ssec:apply-prot} this does not lead to a circularity.
2090: 
2091: Abstractly, we will use the same schedule for join and splits 
2092: as in the proof of Theorem~\ref{thm:balance}. However, we will not
2093: perform as many local update steps during a join or split process.
2094: Moreover, the structural implementation of a join or split will
2095: await its first local update. 
2096: 
2097: We note that level $1$ is exceptional, in that we need
2098: $n_1$ local updates for the split and join postprocessing. This is
2099: trivially obtained if we with each leaf update make $84$ local
2100: updates on any postprocessing involving or tied to the parent. For
2101: any other level $i>1$, we need $\sqrt{n_i}$ local updates, which is
2102: what is obtained below.
2103: 
2104: 
2105: The result will be achieved by a
2106: combination of techniques. We will use a tabulation technique for the
2107: lower levels of the exponential search tree, and a scheduling idea of
2108: Levcopoulos and Overmars \cite{LevcBala} for the upper levels.
2109: 
2110: \subsubsection{Constant update cost for small trees on 
2111: the lower levels}\label{S:low-level}
2112: 
2113: In this subsection, we will consider small trees induced by lower
2114: levels of the multiway tree from Theorem \ref{thm:finger-balance}.
2115: 
2116: One possibility for obtaining constant update cost for search
2117: structures containing a few keys would have been to use atomic heaps
2118: \cite{FW94}.  However, here we aim at a solution using only~AC$^0$
2119: operations.  We will use tabulation. A tabulation technique for finger
2120: updates was also used by Dietz and Raman \cite{DR94}. They achieved
2121: constant finger update time and $O(\log q)$ finger search time, for
2122: $q$ intermediate keys, in the comparison based model of computation.
2123: However, their approach has a lower bound of $\Omega(\log q/\log\log
2124: q)$ as it involves ranks \cite{FS89}, and would prevent us from
2125: obtaining our $O(\sqrt{\log q/\log\log q})$ bound. Finally, we note
2126: that our target is the general schedule for multiway trees in Theorem
2127: \ref{thm:finger-balance} which is not restricted to search
2128: applications. 
2129: 
2130: Below, we present a schedule satisfying the conditions
2131: of Theorem \ref{thm:finger-balance} except that we need tables for an
2132: efficient implementation. 
2133: 
2134: 
2135: Every time we insert or delete a leaf $u$, we will do $1000$ local update
2136: steps from $u$. The place for these local update steps is determined based on a
2137: system of marking and unmarking nodes.  To place a local update from
2138: a leaf $u$, we find its nearest unmarked ancestor $v$. 
2139: We then unmark all nodes on the path from $u$ to $v$ and mark $v$.
2140: If $v$ is
2141: involved in or tied to a join or split process, we perform one local
2142: update step on this process. If not, we check if the weight of $v$ is
2143: such that it should split or join or tie to a neighboring split or
2144: join, as described in the schedule for Proposition \ref{lem:buckets}.
2145: We then mark the involved nodes and perform a local update step at
2146: each of them.
2147: \begin{lemma} For a split or join process on level $i$, we get
2148: at least $n_i/2^i$ local updates steps.
2149: \end{lemma}
2150: Note that $n_i>18^i$, so $n_i/2^i>\sqrt{n_i}$, as in Theorem
2151: \ref{thm:finger-balance}.
2152: \begin{proof}
2153:   First, using a potential function argument, we analyze how
2154:   many time a level $i$ node $v$ gets marked during $p$ local
2155:   updates from leaves below $v$.
2156:   The potential of a marked node is 0 while the potential of an
2157:   unmarked node on level $i$ is $2^i$.  The sub-potential of $v$ is
2158:   the sum of the potential of all nodes descending from or equal to
2159:   $v$. Then, if an update below $v$ does not unmark $v$, it decreases the
2160:   sub-potential by 1. On the other hand, if we unmark $v$, we also
2161:   unmark all nodes on a path from a leaf to $v$, so we increase the
2162:   potential by $2^{i+1}-1$. When nodes are joined and split, the
2163:   involved nodes are all marked so the potential is not increased. The
2164:   potential is always non-negative.  Further, its maximum is achieved
2165:   if all nodes are unmarked. Since all nodes have degree at least 4,
2166:   if all nodes are unmarked, the leaves carries for more than
2167:   half of the potential.  On the other hand, the number of leaves
2168:   below $v$ is at most $n_i$, so the maximum potential
2169:   is less than $2n_i$. It follows that the number of times $v$ gets
2170:   unmarked is more than $(p-2n_i)/2^{i+1}$. Hence $v$ gets
2171:   marked at least $(p-2n_i)/2^{i+1}$ times.
2172:   
2173:   From Theorem \ref{thm:balance} we know that during a split or join
2174:   process, there are at least $n_i/84$ leaf updates below the at most
2175:   $4$ level $i$ nodes $v_0,v_1,v_2,v_3$ involved in or tied to the
2176:   process. Each of these leaf updates results in $1000$ local
2177:   updates. Thus, if $p_j$ is the number of leaf updates from
2178:   below $v_j$ during our process, $p_0+p_1+p_2+p_3\geq 10n_i$.
2179:   Consequently, the number of local updates for our process
2180:   is 
2181: \[\sum_{j=0}^3 (p_j-2n_i)/2^{i+1}\geq (10n_i-8n_i)/2^{i+1}=n_i/2^i,\]
2182:   as desired.
2183: \end{proof}
2184: The above schedule, with the marking and unmarking of nodes to
2185: determine the local update steps, could easily be implemented in time
2186: proportional to the height of the tree, which is $O(\log\log n)$. To
2187: get down to constant time, we will use tables of size $o(n)$ to deal
2188: with small trees with up to $m$ nodes where $m=O(\sqrt{\log n})$. Here
2189: we think of $n$ as a fixed capacity for the total number of
2190: stored keys. As the number of actual keys change by a factor of $2$, we
2191: can build a data structure with new capacity in the background.
2192: 
2193: Consider an exponential search tree $E$ with at most $m$ nodes.  With
2194: every node, we are going to associate a unique index below $m$, which is given
2195: to the node when it is first created by a split. Indices are recycled
2196: when nodes disappear in connection with joins. We will have a table
2197: of size $m$ that maps indices into the nodes in $E$. Conversely, 
2198: with each node in $E$, we will store its index. In
2199: connection with an update, tables will help us find the index to the
2200: node to be marked, and then the table give us the corresponding
2201: node. 
2202: 
2203: Together with the tree $E$, we store a bitstring $\tau_E$ representing
2204: the topology of $E$. More precisely, $\tau_E$ represents the depth first
2205: search traversal of $E$ where 1 means go down and 0 means go up. Hence,
2206: $\tau_E$ has length $2m-2$. Moreover, we have a table $\mu_E$ that maps
2207: depth first search numbers of nodes into indices. Also, we have a table
2208: $\gamma_E$ that for every node tells if it is marked. 
2209: We call 
2210: $\alpha_E=(\tau_E,\mu_E,\gamma_E)$ the signature 
2211: of $E$.  Note that we have $\leq 2^{2m}\times m^m\times 2^m\times O(m) =
2212: m^{O(m)}$ different signatures.
2213: 
2214: For each of the signatures, we tabulate what to do in connection with
2215: each possible leaf update. More precisely, for a leaf delete, we have
2216: a table that takes a signature of tree and the index of the leaf to be
2217: deleted and produces the signature of the tree without the leaf. Thus
2218: when deleting a leaf, we first find its associated index so that we
2219: can use the table to look up the new signature.  Similarly, for a leaf
2220: insert, we assume the index of a preceding sibling, or the parent if
2221: the leaf is to be a first child. The table should produce not only the
2222: new signature, but also the index of the new leaf. This index should
2223: be stored with the new leaf. Also, the leaf should be stored with the
2224: index in the table mapping indices to nodes.
2225: 
2226: For the local updates, we have a table taking a signature and the index
2227: of a leaf to do the local update from. The table produces the
2228: index of the node to be marked, hence at which to do a local update. If a
2229: split or join is to be done, the table tells the indices of involved
2230: nodes. For a split, this includes the child at which to split the children
2231: sequence. Also, it includes the index of the new node. Finally,
2232: the table produces the signature of the resulting tree.
2233: All the above mentioned tables can easily be constructed in $m^{O(m)}=o(n)$ 
2234: time and space.
2235: 
2236: 
2237: Let $a$ be such that $n_a\leq \sqrt{\log n}< n_{a+1}$ \mtch and set 
2238: $m=n_a$. We are
2239: going to use the above tabulation to deal with levels $0,...,a$ of the
2240: multiway tree of Theorem \ref{thm:finger-balance}.  Note that if
2241: $n_1>\sqrt{\log n}$, $a=0$, and then we can skip to the next
2242: subsection (\S \ref{S:high-level}).
2243: With each of the
2244: level $a$ nodes, we store the signature of the descending subtree as
2245: well as the table mapping indices to nodes. Also, with each leaf, we
2246: store an ancestor pointer to its level $a$ ancestor. Then, when a leaf
2247: is added, it copies the ancestor pointer of one of its siblings. Via
2248: these ancestor pointers, we get the signature of the tree that is
2249: being updated.
2250: 
2251: A new issue that arises is when level $a$ nodes $u$ and $v$ get joined 
2252: into $u$. For this case, we temporarily allow indices up to
2253: $2m-1$, and add $m$ to the indices of nodes descending from $v$.
2254: A table takes the signatures of the subtrees of $u$ and $v$ and produce
2255: the signature for the joined tree with these new indices. Also,
2256: we place a forward pointer from $v$ to $u$, so that nodes
2257: below $v$ can find their new ancestor in constant time. To get
2258: the index of a node, we take its current ancestor pointer. If it 
2259: points to a node with a forward pointer, we add $m$ to the 
2260: stored index. Conversely, given an index, if it is not less than
2261: $m$, this tells us that we should use the old table from $v$, though
2262: subtracting $m$ from the index.
2263: 
2264: 
2265: During the postprocessing of the join, we will traverse the subtree
2266: that descended from $v$. We move each node $w$ to $u$, redirecting the
2267: ancestor pointers to $u$ and give $w$ a new unique index below $m$.
2268: Such an index exists because the total size of the tree after the join
2269: is at most $m$.  The indexing is done using a table that suggests the
2270: index and the resulting new signature.  The node is then inserted in the
2271: table at $u$ mapping indices below $m$ to nodes. Since we use the same
2272: general schedule as that in Theorem \ref{thm:balance}, we know that we
2273: have $n_a/84$ updates below the join before the join needs to be
2274: completed. In that time, we can make a post traversal of all the at
2275: most $n_a$ descendants of the join, assigning new indices and updating
2276: parent pointers. We only deal with a constant number of descendants at
2277: the time. For the traversal, we can use a depth first traversal,
2278: implemented locally as follows. At each point in time, we are at some
2279: node $w$, going up or down. We start going down at that first child of
2280: $v$ from when the join was made. If we are going down, we move $w$ to
2281: its first child. If we are going up and there is a sibling to the
2282: left, we go to that sibling, going down from there. If we are going up
2283: and there is no sibling to the left, we go up to the parent. At each
2284: node, we check if it has already been moved to $u$ by checking if
2285: the ancestor pointer points to $u$. If we are
2286: about to join or split the traversal node $w$, we first move $w$ away
2287: a constant number of steps in the above traversal. This takes constant
2288: time, and does not affect the time bounds for join and split.
2289: 
2290: A level $a$ split of $u$ into $u$ and $v$ is essentially symmetric
2291: but simpler in that we do not need to change the indices. In the
2292: traversal of the new subtree under $v$, we only need to redirect
2293: the ancestor pointers to $v$ and to build the table mapping indices
2294: to nodes in the new subtree. 
2295: 
2296: The traversals take constant time for level $a$ join and split processes 
2297: for each descending leaf updates. In the next subsection, we are going
2298: to do corresponding traversals for two other distinguished levels.
2299: 
2300: 
2301: Including the new tables for index pairs, all tables are constructed
2302: in $m^{O(m)}=o(n)$ time and space. With them, we implement the
2303: schedule of Theorem \ref{thm:finger-balance} for levels $i=0,..,a$
2304: using constant time and a constant number of local update steps per
2305: leaf update, yet providing at least $\sqrt{n_i}$ local updates for the
2306: postprocessing of each join or split.
2307: 
2308: 
2309: \subsubsection{Moving up the levels}\label{S:high-level}
2310: We are now going to implement the schedule of
2311: Theorem~\ref{thm:finger-balance} on levels $a+1$ and above. \mtch In
2312: connection with a leaf update, we have constant time access to its
2313: level $a$ ancestor, hence also to its level $a+1$ ancestor.  We note
2314: that if $n_1>\sqrt{\log n}$, $a=0$, and then we are not using any of
2315: the material from the previous subsection (\S \ref{S:low-level}). Then
2316: the whole construction will be implementable on a pointer machine.
2317: 
2318: 
2319: To get to levels $a+1$ and above, we are going to use the following 
2320: variant of a lemma of Overmars and 
2321: Levcopoulos \cite{LevcBala}:
2322: \begin{lemma}\label{lem:counters} 
2323: Given $p$ counters, all starting at zero, and an adversary incrementing these
2324: counters arbitrarily. Every time 
2325: the adversary has made $q$ increments, the increments being by one at
2326: the time, we subtract $q$ from some largest counter, or set
2327: it to zero if it is below $q$. Then the largest possible
2328: counter value is $\Theta(q\log p)$. 
2329: \end{lemma}
2330: In the original lemma from  \cite{LevcBala}, instead of subtracting
2331: $q$ from a largest counter, they split it into
2332: two counters of equal size. That does not imply our case, so we need our own 
2333: proof, which also happens to be much shorter. 
2334: \begin{proof}
2335: We want to show that the maximal number of counters larger 
2336: than $2iq$ is at most $p/2^i$. The proof is by induction. 
2337: Obviously, the statement is true for $i=0$, so consider $i>0$.
2338: Consider a time $t$ where the number of counters larger than
2339: $p/2^i$ is maximized, and let $t^-$ be the last time before
2340: $t$ at which the largest counter was $(2i-1)q$. 
2341: 
2342: We consider it one step to add $1$ to $q$ counters, and subtract
2343: $q$ from a largest counter. Obviously, at the end of the day, we
2344: can at most do $q$ better in total.
2345: 
2346: The basic observation is that between $t^-$ and $t$, no change
2347: can increase the sum of the counter excesses above $(2i-2)q$, for
2348: whenever we subtract $q$ it is from a counter which is
2349: above $(2i-1)q$. However, at time $t^-$, by induction, we
2350: had only $p/2^{i-1}$ counters above $(2i-2)q$, and each
2351: had an excess of at most $q$. To get to $2iq$, a counter
2352: needs twice this excess, and since the total excess can
2353: only go down, this can happen for at most half the counters.
2354: \end{proof}
2355: For the implementation of Lemma \ref{lem:counters}, we have
2356: \begin{lemma}\label{lem:impl-counter}
2357: Spending constant time per counter increment in Lemma \ref{lem:counters},
2358: the largest counter to be reduced can be found in constant time.
2359: \end{lemma}
2360: \begin{proof} We simply maintain a doubly linked sorted list of counter
2361: values, and with each value we have a bucket with the counters with
2362: that value. When a counter $c$ is increased from $x$ to $x+1$, we check
2363: the value $x'$ after $x$ in the value list. If $x'>x+1$, we insert $x+1$
2364: into the value list with an associated bucket. We know move $c$ to the
2365: bucket of $x+1$, removing $x$ if its bucket gets empty. Decrements by one
2366: can be handled symmetrically. Thus, when a largest counter $a$ has been
2367: picked, during the next $k$ increments, we can decrement $a$ by one.
2368: \end{proof}
2369: We are going to use the above lemmas in two bands, one on levels
2370: $a+1,...,b$ where $b$ is such that $n_b\leq (\log n)^{\log\log n}<
2371: n_{b+1}$, and one levels $b+1$ and up. First, we consider levels
2372: $a+1,...,b$.
2373: 
2374: To describe the basic idea, for simplicity, we temporarily assume that
2375: there are no joins or splits.  Set $q=b-a$.
2376: For $i=a+1,...,b$, during $\Omega(n_i)$ leaf updates
2377: below a node $v$ on level $i$, we will get $\Omega(n_i/q)$ local updates
2378: at $v$. Since $n_{i+1}>18 n_i$, $q<\log_{18} (n_b/n_a)<(\log\log n)^2$.
2379: On the other hand, $n_i\geq n_{a+1}>\sqrt{\log n}$, so $q=o(\sqrt{n_i})$.
2380: 
2381: Each level $a+1$ node $v$ has a counter that is incremented every time
2382: we have a leaf update below $v$.  In the degenerate case where $a=0$,
2383: we always make a local update at $v$ so as to get enough updates on
2384: level $1$ as required by Theorem~\ref{thm:finger-balance}. \mtch We
2385: make an independent schedule for the subtree descending from each
2386: level $b$ node $u$.  Once for every $q$ updates below $u$, we pick a
2387: descending level $i$ node with the largest counter, do a local update
2388: at $v$, and subtract $q$ from the counter. During the next $q-1$ leaf
2389: updates below $u$, we follow the path up from $v$ to $u$, doing a
2390: local update at each node on the way.
2391: 
2392: A largest counter below $u$ is maintained as described in 
2393: Lemma~\ref{lem:impl-counter}. The number of counters below $u$ is
2394: at most $p=n_b/(n_a/4)$, so by Lemma~\ref{lem:counters}, the
2395: maximal counter value is $O(q\log p)=O((\log n_b)^2)=O((\log\log n)^4)$.
2396: 
2397: 
2398: Now, for $i=a+1,...,b$, consider a level $i$ node $w$. The maximal
2399: number of counters below $w$ is $n_i/(4n_{a+1})$, so their total
2400: value is at most 
2401: \[O((n_i/n_{a+1})(\log\log n)^4)=O((n_i/\sqrt{\log n})(\log\log n)^4)=o(n_i).\]
2402: Each update below $w$ adds one to this number. Moreover, we
2403: do a local update at $w$ every time we subtract $q$ from one of the
2404: descending counters, possibly excluding the very last subtraction if we have
2405: not passed $w$ on the path up to $u$. Consequently, during $r=\Omega(n_i)$
2406: leaf updates below $w$, the number of local updates at $w$ is at least
2407: \[(r-o(n_i)-q)/q=\Omega(n_i/q)=\omega(\sqrt{n_i}).\]
2408: Next, we show how to maintain approximate weights. For the nodes $v$ on level $a+1$, we assume we
2409: know the exact weight $W_v$. For  nodes $w$ on
2410: levels $i=a+1,...,b$, we have an approximate weight $\widehat W_w$.
2411: When the counter of a level $a+1$ node $v$ is picked, we set
2412: $\Delta=W_v-\widehat W_v$ and $\widehat W_v=W_v$. As we
2413: move up from $v$ to $u$ during the next $q-1$ updates, at each
2414: node $w$, we set $\widehat W_v=\widehat W_v+\Delta$.
2415: 
2416: We will now argue that for any node $w$ on level $i=a+1,...,b$, the
2417: absolute error in our approximate weight $\widehat W_w$ is $o(n_i)$. 
2418: The error  in $\widehat W_w$ is at most the sum of the counters below $w$ 
2419: plus $q$, and we have already seen above that this value is $o(n_i)$. It
2420: follows that 
2421: \[W_w=(1\pm o(1))\widehat W_w.\]
2422: This error is small enough that we can use the approximate weights for
2423: the scheduling of split and joins. More precisely, in the analysis,
2424: we rounded at various points, and the rounding left room for errors below
2425: a constant fraction.
2426: 
2427: We are now ready to describe the details of the schedule as nodes get
2428: joined and split. From the last subsection, we have ancestor pointers
2429: to level $a$, and via table we can also get the exact weight. From
2430: this, we can easily get ancestor pointers and exact weights on level
2431: $a+1$. On level $a+1$, we can then run the join and split schedule from
2432: Section \ref{ssec:apply-prot}. 
2433: 
2434: For level $i=a+2,...,b$, we use the approximate weights both for
2435: the nodes and for the children. When we get a local update at
2436: a node $w$, we know that $\widehat W_w$ has just been updated
2437: and that it equals the sum of the weights of the children, so
2438: we do have local consistency in the approximate weights. We then
2439: use the new approximate weight in the schedule of Proposition
2440: \ref{lem:buckets} to check if $w$ is to be joined or split or
2441: tied to some other join or split process. The local update
2442: step is applied to any join or split process neighboring $w$.
2443: 
2444: Finally, we use the traversal technique from the last subsection
2445: to maintain ancestor pointers to level $b$ nodes. This means
2446: that we use constant time on level $b$ in connection with each
2447: leaf update. In connection with a join or split postprocessing
2448: on level $b$, this time also suffice to join or split the priority
2449: queue over counters below the processed nodes. This completes
2450: our maintenance of levels $a+1,....,b$.
2451: 
2452: For the levels above $b$, we use the same technique as we did for
2453: levels $a+1,....,b$, but with the simplification that we have only one
2454: tree induced by levels above $b$. Consequently, we have only one
2455: priority queue over all counters on level $b$.  The numbers, however,
2456: are a bit different.  This time, the number $q'$ of levels is
2457: $\log_{18} (n/n_b)<\log n$.  However, for $i>b$, $n_i>(\log
2458: n)^{\log\log n}$, so $q'=o(\sqrt{n_i})$.
2459: 
2460: We have one priority queue over all counters on level $b$, of which
2461: there are at most $p'=n/(n_{b+1}/4)$, so by Lemma~\ref{lem:counters}, the
2462: maximal counter value is $O(q'\log p')=O(\log n(\log\log n)^2)$.
2463: 
2464: Now, for $i>b$, consider a level $i$ node $w$. The maximal
2465: number of counters below $w$ is $n_i/(4n_{b+1})$, so their total
2466: value is at most 
2467: \[O((n_i/n_{b+1})\log n(\log\log n)^2)=O((n_i/\log n^{\log\log n})
2468: \log n(\log\log n)^2)=o(n_i).\]
2469: With the above changes in numbers, we use the same technique for
2470: levels above $b$ as we used for levels $a+1,...,b$. 
2471: {\bf This completes the proof of Theorem \ref{thm:finger-balance}}
2472: 
2473: \begin{corollary}\label{cor:finger-search-balance}
2474: Given a number series $n_0,n_1, n_2<, \ldots$, with $n_0=1$, $n_1\geq 84$, 
2475: $n_i^2>n_{i+1} >
2476: 18 n_i$, we maintain a multiway tree where each node on height $i$ 
2477: which is neither the root nor a leaf node has weight between $n_i/4$ and 
2478: $n_i$. If an $S$-structure for a node on height $i$ 
2479: can be built in $O(\sqrt{n_{i-1}})$ time, or $O(n_1)$ time for
2480: level $1$, we can maintain $S$-structures
2481: for the whole tree in constant time per finger update.
2482: \end{corollary}
2483: \begin{proof} We use the same proof as the one we used to
2484: prove Corollary \ref{cor:search-balance} from Theorem \ref{thm:finger-balance}.
2485: \end{proof}
2486: 
2487: \subsection{Fast finger search}
2488: 
2489: We first concentrate on implementing a fast finger search, postponing
2490: the constant time finger updates to the next subsections.  For
2491: simplicity, we will always assume that the fingered key $x$ is smaller
2492: than the key $y$ sought for. The other case can be handled by a
2493: ``mirror'' data structure where each key $x$ is replaced by $U-x$,
2494: where $U$ is the largest possible key.
2495: 
2496: The following finger search analog of Theorem 
2497: \ref{thm:search-red} is obtained using the same kind of methods
2498: as for pointer based finger search structures, i.e. by the use of 
2499: horizontal links.
2500: \begin{theorem}\label{lem:finger-red-top}
2501: Suppose a static search structure on
2502: $d$ integer keys can be constructed in $O(d^{(k-1)/2})$, $k\geq 2$,  
2503: time and space so given a finger to a stored key $x$, we can search
2504: a key $y>x$ in time $S(d,y-x)$. We can then construct
2505: a dynamic linear space search structure that with $n$ integer keys supports 
2506: finger updates in time constant time and 
2507: finger searches in time $T(q,y-x)$ where $q$ is the number of
2508: stored keys between $x$ and $y$ and
2509: $T(n)\leq T(n^{1-1/k})+O(S(n,y-x))$. Here $S$ is supposed
2510: to be non-decreasing in both arguments. The reduction itself uses only 
2511: standard AC$^0$ operations.
2512: \end{theorem}
2513: \begin{proof}
2514: We use an exponential search tree where on each level we have horizontal
2515: links between neighboring nodes. It is trivial to modify join and
2516: split to leave horizontal pointers between neighboring nodes on the
2517: same level. 
2518: 
2519: A level $i$ node has $O(n_i/n_{i-1})=O(n_i^{1/k})$ children, so, by
2520: assumption, its $S$-structure is built in
2521: time $O(n_i^{(k-1)/(2k)})=O(\sqrt{n_{i-1}})$. Hence we can
2522: apply Corollary \ref{cor:finger-search-balance}, and maintain
2523: $S$-structures at all nodes in constant time per finger update.
2524: 
2525: To search for $y>x$, given a finger to $x$, 
2526: we first traverse the path up the tree from the leaf containing $x$. 
2527: At each level, we examine
2528: the current node and its right neighbor until a node $v$ is found
2529: that contains $y$. Here the right neighbor is found in constant time
2530: using the horizontal links between neighbors. As we shall see later, 
2531: the node $v$ has the advantage that its largest possible
2532: degree is closely related to $q$.
2533: 
2534: Let $u$ be the child of $v$ containing $x$ and let $x'$ be
2535: the separator immediately to the right of $u$.
2536: Then, $x\leq x'\leq y$, and if we start our search from $x'$,
2537: we will find the child $w$ where $y$ belongs in $S(d,y-x') \leq S(d,y-x)$ time,
2538: where $d$ is the degree of $v$.
2539: 
2540: We now search down from $w$ for $y$. At 
2541: each visited node, the left splitter $x'$ satisfies $x\leq x'\leq y$
2542: so we start our search from the left splitter.
2543: 
2544: We are now going to argue that the search time is $T(q,y-x)\leq
2545: T(q^{1-1/k})+O(S(q,y-x))$, as stated in the lemma. Let $i$ be the
2546: level of the node $v$. Let $u$ be the level $i-1$ ancestor of the leaf
2547: containing $x$, and let $u'$ be the right neighbor of $u$. By definition of
2548: $v$, $y$ does not belong to $u'$, and hence all keys below $u'$ are
2549: between $x$ and $y$. It follows that $q\geq n(u')\geq
2550: n_{i-1}/10$. Now, the recursive search bound follows using the
2551: argument from the proof of Lemma \ref{lem:search-red}.
2552: \end{proof}
2553: 
2554: Note in the above lemma, that it does not matter whether the static 
2555: search structure supports efficient finger search in terms of the number $d$ 
2556: of intermediate keys. For example, the static search bound of 
2557: $O(\sqrt{\log n/\log\log n})$ from \cite{BF99} immediately implies 
2558: a dynamic finger search bound of $O(\sqrt{\log q/\log\log q})$ where
2559: $q$ is the number of stored keys between the fingered key $x$ and the 
2560: sought key $y$. However, if we want efficiency in terms of $y-x$, we
2561: need the following result.
2562: \begin{lemma}
2563: \label{lem:loglogxy}
2564: A data structure storing a set $X$ of $d$ keys from a universe of size $U$
2565: can be constructed in $d^{O(1)}$ time and space such that
2566: given a finger to stored key $x\in X$, we search a key $y>x$ in 
2567: time~$O(\log\log (y-x)/ \log\log\log (y-x))$.
2568: \end{lemma}
2569: \begin{proof}
2570: Beame and Fich \cite{BF99} have shown that a polynomial space
2571: search structure can be constructed with search time 
2572: $O(\min\{\sqrt{\log n/\log\log n},\log\log U/\log\log U\})$, where $n$ 
2573: is the number of keys and $U = 2^{\wordlength}$ is the size of the universe they are drawn
2574: from. As a start, we will have one such structure over our $d$ keys.
2575: This gives us a search time of $O(\sqrt{\log d/\log\log d})$. Hence
2576: we are done if 
2577:  $\log\log (y-x)/ \log\log\log (y-x)=\Omega(\sqrt{\log d/\log\log d})$, and
2578: this is the case if $y-x\geq 2^d$.
2579: 
2580: 
2581: Now, for each key $x\in X$, and for $i=0,...,\log\log d$, we will
2582: have a search structure $S_{x,i}$ over the keys in the range
2583: $[x,x+2^{2^{2^i}})$, with search time $O(\log\log
2584: 2^{2^{2^i}}/\log\log\log 2^{2^{2^i}})=O(2^i/i)$. Then to find $y<x+2^d$,
2585: we look in $S_{x,\lceil \log\log\log (y-x)\rceil}$. Now,
2586: $2^{2^{2^{\lceil \log\log\log (y-x)\rceil}}}<(y-x)^{\log(y-x)}$, the
2587: search time is $O(\log\log (y-x)^{\log(y-x)}/\log\log\log (y-x)^{\log(y-x)})=
2588: O(\log\log (y-x)/\log\log\log (y-x))$.
2589: 
2590: It should be noted that it is not a problem to find the appropriate
2591: $S_{x,i}$. Even if for each $x$, we store the $S_{x,i}$ as a linked
2592: list together with the upper limit value of $x+2^{2^{2^i}}$, we can get
2593: to the appropriate $S_{x,i}$ by starting at $S_{x,0}$ and moving
2594: to larger $S_{x,i}$ until $y<x+2^{2^{2^i}}$. This 
2595: takes $O(\log\log\log (y-x))=o(\log\log (y-x)/\log\log\log (y-x))$ steps.
2596: 
2597: Finally, concerning space and construction time, since we only have
2598: $O(\log\log d)$ search structures for each of the $d$ elements in $X$,
2599: polynomiality follows from polynomiality of the search structure of
2600: Beame and Fich.
2601: \end{proof}
2602: \begin{prooft}{thm:finger} The result follows directly from 
2603: the reduction of Theorem \ref{lem:finger-red-top} together with
2604: the static search structures in Theorem \ref{thm:static-search},
2605: Theorem \ref{thm:BF99}, and Lemma \ref{lem:loglogxy}.
2606: \end{prooft}
2607: 
2608: \section{String searching}\label{sec:string}
2609: In this section, we prove Theorem \ref{thm:string}.
2610: 
2611: \subsection{Preliminaries}
2612: Our string searching result utilizes Corollary \ref{cor:search} and
2613: Proposition \ref{obs:hash}.
2614: 
2615: \paragraph{Tries}
2616: As a basic component, we use a trie over the strings where the characters are
2617: 1-word integers \cite[\S III]{Meh84}.  For technical reasons, we
2618: assume that each string ends with a special character $\bot$, hence that no
2619: string is a prefix of any other string. Abstractly, a trie over a set
2620: $S$ of strings is the rooted tree whose nodes are the prefixes of
2621: strings in $S$. For a string $\alpha$ and a 1-word character $a$,
2622: the node $\alpha a$ 
2623: has parent $\alpha$ and is labeled $a$.  The root is not labeled,
2624: so $\alpha a$ is the labels encountered on the path from the root to
2625: the node $\alpha a$. Our trie is ordered in the sense that the
2626: children of a node are ordered according to their labels.  
2627: We use standard path (or Patricia) compression, so
2628: paths of unary nodes are stored implicitly by
2629: pointers to the stored strings. Hence the trie data structure is
2630: really concentrated on the $O(n)$ branching nodes. 
2631: 
2632: By storing appropriate
2633: pointers, the problem of searching a string $x$ among the stored
2634: strings $S$ reduces to (1) finding the longest common prefix
2635: $\alpha$ between $x$ and the strings in $S$, and (2) searching the
2636: next 1-word character of $x$ among the labels of the children of the
2637: trie node $\alpha$. 
2638: In a static implementation, we would use a dictionary in each node,
2639: which would allow us to spend constant time at each visited node during 
2640: step (1). Then, by 
2641: keeping a search structure from Corollary \ref{cor:search} 
2642: at each branching node, we perform step (2) in
2643: $O(\sqrt{\log n/\log\log n})$ time, which is fine. 
2644: 
2645: However, in a dynamic setting we cannot use dictionaries
2646: in each node over all children since we cannot update linear
2647: spaced dictionaries
2648: efficiently in the worst case. Instead, we will sometimes allow step (1)
2649: to spend more than constant time in each visited node. This is fine
2650: as long as the total time spent in step (1) does not exceed the total
2651: bound aimed at.
2652: 
2653: \subsection{Efficient traversal down a trie}
2654: Our new idea is to only apply the constant time dictionaries
2655: to some of the children.
2656: In a trie node, we differ between "heavy" and "light" children,
2657: depending on their number of descending leaves. The point is that
2658: heavy children will remain for a long time, and hence we can store them in
2659: a dictionary which is rebuilt during a relatively slow
2660: rebuilding process. For light children, we cannot use a dictionary, 
2661: instead we store them in a dynamic search structure 
2662: from Corollary \ref{cor:search}.
2663: Although this will give rise to a non-constant search time, we are
2664: still fine since the low weight of the found child will guarantee that
2665: the problem size has decreased enough to compensate for the search effort.
2666: 
2667: In more detail: At a node with weight $m$, we only 
2668: store heavy children with $\Omega(m^{1-1/k})$ descending keys
2669: in a dictionary, 
2670: where $k=2+\eps$ is the exponent from the dictionaries in 
2671: Proposition \ref{obs:hash}, the other children are stored in a dynamic search 
2672: structure (an exponential search tree). 
2673: Our string searching time is then $O(\ell)$ 
2674: for the use of dictionaries
2675: and for following pointers. The total cost of using the search structures
2676: bounded by $T(n)$, where
2677: \begin{eqnarray*}
2678: T(m)&\leq&O(\sqrt{\log m/\log\log m})+T(m^{1-1/k})\\
2679: &=&O(\sqrt{\log m/\log\log m}).
2680: \end{eqnarray*}
2681: Adding up, our total time bound is $O(\sqrt{\log n/\log\log n}+\ell)$, which
2682: is optimal.
2683: 
2684: We maintain the dictionary of a node $v$ by periodic rebuilding. We maintain
2685: an unordered list of all children with more than $m^{1-1/k}/2$ descendants. 
2686: In every period, we first scan the list, and then build a dictionary
2687: over the labels of the scanned children. When the new dictionary is completed
2688: it replaces the previous one in constant time.
2689: There are only $O(m^{1/k})$ labels,
2690: so this takes $O(m^{1/k\cdot(k-1)})=O(m^{1-1/k})$ time. Hence, spending
2691: $O(1)$ time per update to a descendant, 
2692: we can complete a period for every $m^{1-1/k}/4$ updates, and this 
2693: ascertains that no child can contain more than $m^{1-1/k}$ children
2694: without being in the current dictionary.
2695: 
2696: The space bound is proven in a rather straightforward manner.
2697: 
2698: 
2699: \paragraph{Practical simplifications}
2700: In our reduction, we used a polynomial spaced dictionary
2701: from Proposition \ref{obs:hash}. By increasing the exponent, 
2702: we can allow ourself
2703: to use even simpler and faster hashing schemes, such as 1-level
2704: hashing with quadratic space, which would remove collision handling.
2705: This way of using space seems to be a good idea also for
2706: more practical randomized data structures.
2707: 
2708: 
2709: \section{Other applications of our techniques}\label{sec:other-appl}
2710: In this section we discuss how the techniques presented in this
2711: paper have been applied in other contexts.
2712: 
2713: Variants of exponential search trees have been instrumental in many
2714: of the previous strongest results on deterministic linear integer
2715: space sorting and priority queues \cite{And96,Tho98,AT00,Han01}. Here
2716: a priority queue is a dynamic set for which we maintain the minimum
2717: element.  When first introduced by Andersson \cite{And96}, they
2718: provided the then strongest time bounds of $O(\sqrt{\log n})$ for
2719: priority queues and $O(n\sqrt{\log n})$ for sorting.  As noted by
2720: Thorup in \cite{Tho98}, we can surpass the $\Omega(\sqrt{\log
2721:   d/\log\log d})$ lower bound for static polynomial space searching in
2722: a set of size $d$ if instead of processing one search at the time, we
2723: process a batch of $d$ searches. Thorup got the time per key in the
2724: batch down to $O(\log\log d)$. In order to exploit this, Thorup
2725: developed an exponential priority queue tree where the update time was
2726: bounded by \req{eq:rec}, but with $S(n)$ being the per key cost of
2727: batched searching. Thus he got priority queues with an update time of
2728: $O((\log\log n)^2)$ and hence sorting in $O(n(\log\log n)^2)$ time.
2729: Thorup's original construction was amortized, but a worst-case
2730: construction was later presented by Andersson and Thorup \cite{AT00}.
2731: More advanced static structures for batched searching where later
2732: developed by Han \cite{Han01} who also increased the batch size to
2733: $d^2$. He then ended up with a priority queue update time $O((\log\log
2734: n)(\log\log\log n))$ and sorting in $O(n(\log\log n)(\log\log\log n))$
2735: time.  However, exponential search trees are not used in Han's recent
2736: deterministic $O(n\log\log n)$ time sorting in linear space
2737: \cite{Han02} or in Thorup's \cite{Tho02} corresponding priority queue
2738: with $O(\log\log n)$ update time.  Since \req{eq:rec} cannot give
2739: bounds below $O(\log\log n)$ per key, so it looks as if the role of
2740: exponential search trees is played out in the context of integer
2741: sorting and priority queues.
2742: 
2743: Recently, Bender, Cole, and Raman \cite{BCR02} have used 
2744: the techniques for to derive worst-case efficient cache-oblivious
2745: algorithms for several data structure problem. This nicely highlights
2746: that the exponential search trees themselves are not restricted to integer
2747: domains. It just happens that our applications in this paper are for
2748: integers.
2749: 
2750: Theorem \ref{thm:balance} provides a general tool for maintaining
2751: balance in multiway trees. These kind of techniques have been used
2752: before, but they have never been described in an such a general
2753: independent quotable way.  By using our theorems, many proofs of
2754: dynamization can be simplified, and in particular, we can avoid the
2755: standard hand-waving, claiming without proper proof that amortized
2756: constructions can be deamortized.  The second author \cite{Tho02} has
2757: recently used our Proposition \ref{lem:buckets} in a general reduction
2758: from priority queue to sorting, providing a priority queue whose
2759: update cost is the per key cost of sorting. Also, he \cite{Tho02a} has
2760: recently used Theorem \ref{thm:balance} in a space efficient solution
2761: to dynamic stabbing, i.e., the problem of maintaining a dynamic set of
2762: intervals where the query is to find an interval containing a given
2763: point. This codes problems like method look-up in object oriented
2764: programming and IP classification for firewalls on the internet. The
2765: solution has query time $O(k)$, update time $O(n^{1/k})$, and uses
2766: linear space. Previous solutions used space $O(n^{1+1/k})$. The
2767: solution does not involve any search structure, so it is important
2768: that Theorem \ref{thm:balance} has a general format not specialized to
2769: search applications.
2770: 
2771: 
2772: \section{An open problem}\label{sec:open-problem}
2773: It is an interesting open problem what is the right complexity
2774: for searching with standard, or even non-standard, AC$^0$ operations?
2775: Andersson et.al. \cite{AMRT96}, have shown that even if we allow
2776: non-standard AC$^0$ operations, the exact complexity of membership queries
2777: is $\Theta(\sqrt{\log/\log\log n})$. This contrast the situation at the RAM,
2778: where we can get down to constant time for membership queries. Interestingly,
2779: $\Theta(\sqrt{\log/\log\log n})$ is also the RAM lower bound for
2780: searching, so the question is potentially, it is possible to
2781: do the $\Theta(\sqrt{\log/\log\log n})$ searching using AC$^0$ operations
2782: only.
2783: 
2784: %\bibliographystyle{plain}
2785: %\bibliography{paper}
2786: 
2787: \begin{thebibliography}{10}
2788: 
2789: \bibitem{And95}
2790: A.~Andersson.
2791: \newblock Sublogarithmic searching without multiplications.
2792: \newblock In {\em Proc. $36^{th}$ FOCS}, pages 655--663, 1995.
2793: 
2794: \bibitem{And96}
2795: A.~Andersson.
2796: \newblock Faster deterministic sorting and searching in linear space.
2797: \newblock In {\em Proc. $37^{th}$ FOCS}, pages 135--141, 1996.
2798: 
2799: \bibitem{AMRT96}
2800: A.~Andersson, P.B. Miltersen, S.~Riis, and M.~Thorup.
2801: \newblock Static dictionaries on {AC}$^0$ {RAM}s: Query time
2802:   ${\Theta(\sqrt{\log n/\log \log n})}$ is necessary and sufficient.
2803: \newblock In {\em Proc. $37^{th}$ FOCS}, pages 441--450, 1996.
2804: 
2805: \bibitem{AMT99}
2806: A.~Andersson, P.B. Miltersen, and M.~Thorup.
2807: \newblock Fusion trees can be implemented with {AC}$^0$ instructions only.
2808: \newblock {\em Theoretical Computer Science}, 215(1-2):337--344, 1999.
2809: 
2810: \bibitem{AT00}
2811: A.~Andersson and M.~Thorup.
2812: \newblock Tight(er) worst-case bounds on dynamic searching and priority queues.
2813: \newblock In {\em Proc. $32^{th}$ STOC}, pages 335--342, 2000.
2814: 
2815: \bibitem{AT01}
2816: A.~Andersson and M.~Thorup.
2817: \newblock Dynamic string searching.
2818: \newblock In {\em Proc. 12th SODA}, pages 307--308, 2001.
2819: 
2820: \bibitem{BF99}
2821: P.~Beame and F.~Fich.
2822: \newblock Optimal bounds for the predecessor problem and related problems.
2823: \newblock {\em Journal of Computer and System Sciences}, 65(1):38--72, 2002.
2824: \newblock Announced at STOC'99.
2825: 
2826: \bibitem{BCR02}
2827: M.~Bender, R.~Cole, and R.~Raman.
2828: \newblock Exponential structures for cache-oblivious algorithms.
2829: \newblock In {\em Proc. 29th ICALP}, pages 195--207, 2001.
2830: 
2831: \bibitem{BrodFing}
2832: G.~S. Brodal, G.~Legogiannis, C.~Makris, A.~Tsakalidis, and K.~Tsichlas.
2833: \newblock Optimal finger search trees in the pointer machine.
2834: \newblock In {\em Proc. $34^{th}$ STOC}, pages 583--591, 2002.
2835: 
2836: \bibitem{BMM97}
2837: A.~Brodnik, P.~B. Miltersen, and I.~Munro.
2838: \newblock Trans-dichotomous algorithms without multiplication - some upper and
2839:   lower bounds.
2840: \newblock In {\em Proc. $5^{th}$ WADS, LNCS 1272}, pages 426--439, 1997.
2841: 
2842: \bibitem{ChenUsin}
2843: S.~Chen and J.~H. Reif.
2844: \newblock Using difficulty of prediction to decrease computation: Fast sort,
2845:   priority queue and convex hull on entropy bounded inputs.
2846: \newblock In {\em Proc. $34^{th}$ FOCS}, pages 104--112, 1993.
2847: 
2848: \bibitem{Com29}
2849: L.~J. Comrie.
2850: \newblock The hollerith and powers tabulating machines.
2851: \newblock {\em Trans. Office Machinary Users' Assoc., Ltd}, pages 25--37,
2852:   1929-30.
2853: 
2854: \bibitem{CormAlgo}
2855: Th.~H. Cormen, Ch.~E. Leiserson, R.~L. Rivest, and C.~Stein.
2856: \newblock {\em Introduction to algorithms}.
2857: \newblock MIT Press, McGraw-Hill, 2nd edition, 2001.
2858: \newblock ISBN 0-262-03293-7, 0-07-013151-1.
2859: 
2860: \bibitem{DR94}
2861: P.F. Dietz and R.~Raman.
2862: \newblock A constant update time finger search tree.
2863: \newblock {\em Inf. Proc. Lett.}, 52:147--154, 1994.
2864: 
2865: \bibitem{Dum56}
2866: A.~I. Dumey.
2867: \newblock Indexing for rapid random access memory systems.
2868: \newblock {\em Computers and Automation}, 5(12):6--9, 1956.
2869: 
2870: \bibitem{FJ59}
2871: L.~R. Ford and S.~M. Johnson.
2872: \newblock A tournament problem.
2873: \newblock {\em Amer. Math. Monthly}, 66(5):387--389, 1959.
2874: 
2875: \bibitem{FredStor}
2876: M.~L. Fredman, J.~Koml{\'o}s, and E.~Szemer{\'e}di.
2877: \newblock Storing a sparse table with ${O}(1)$ worst case access time.
2878: \newblock {\em Journal of the ACM}, 31(3):538--544, 1984.
2879: 
2880: \bibitem{FW93}
2881: M.~L. Fredman and D.~E. Willard.
2882: \newblock Surpassing the information theoretic bound with fusion trees.
2883: \newblock {\em J. Comput. Syst. Sci.}, 47:424--436, 1993.
2884: \newblock Announced at STOC'90.
2885: 
2886: \bibitem{FW94}
2887: M.~L. Fredman and D.~E. Willard.
2888: \newblock Trans-dichotomous algorithms for minimum spanning trees and shortest
2889:   paths.
2890: \newblock {\em J. Comput. Syst. Sci.}, 48:533--551, 1994.
2891: 
2892: \bibitem{FS89}
2893: M.L. Fredman and M.E. Saks.
2894: \newblock The cell probe complexity of dynamic data structures.
2895: \newblock In {\em Proc. 21$^{st}$ STOC}, pages 345--354, 1989.
2896: 
2897: \bibitem{HMP01}
2898: T.~Hagerup, P.~B. Miltersen, and R.~Pagh.
2899: \newblock Deterministic dictionaries.
2900: \newblock {\em J. Algorithms}, 41(1):69--85, 2001.
2901: 
2902: \bibitem{Han01}
2903: Y.~Han.
2904: \newblock Improved fast integer sorting in linear space.
2905: \newblock {\em Inform. Comput.}, 170(8):81--94, 2001.
2906: \newblock Announced at STACS'00 and SODA'01.
2907: 
2908: \bibitem{Han02}
2909: Y.~Han.
2910: \newblock Fast integer sorting in linear space.
2911: \newblock In {\em Proc. $34^{th}$ STOC}, pages 602--608, 2002.
2912: 
2913: \bibitem{KR84}
2914: D.~Kirkpatrick and S.~Reisch.
2915: \newblock Upper bounds for sorting integers on random access machines.
2916: \newblock {\em Theor. Comp. Sc.}, 28:263--276, 1984.
2917: 
2918: \bibitem{Kn3}
2919: D.~E. Knuth.
2920: \newblock {\em The Art of Computer Programming, Volume 3: Sorting and
2921:   Searching}.
2922: \newblock Addison-Wesley, Reading, Massachusetts, 1973.
2923: \newblock ISBN 0-201-03803-X.
2924: 
2925: \bibitem{Meh84}
2926: K.~Mehlhorn.
2927: \newblock {\em Data Structures and Algorithms 1: Sorting and Searching}.
2928: \newblock Springer-Verlag, 1984.
2929: \newblock ISBN 3-540-13302-X.
2930: 
2931: \bibitem{MN90}
2932: K.~Mehlhorn and S.~{N\"{a}hler}.
2933: \newblock Bounded ordered dictionaries in ${O}(\log\log n)$ time and ${O}(n)$
2934:   space.
2935: \newblock {\em Inf. Proc. Lett.}, 35(4):183--189, 1990.
2936: 
2937: \bibitem{LevcBala}
2938: M.~H. Overmars and C.~Levcopoulos.
2939: \newblock A balanced search tree with {O}(1) worst-case update time.
2940: \newblock {\em Acta Informatica}, 26:269--277, 1988.
2941: 
2942: \bibitem{Ram96}
2943: R.~Raman.
2944: \newblock Priority queues: small, monotone and trans-dichotomous.
2945: \newblock In {\em Proc. 4$^{th}$ ESA, LNCS 1136}, pages 121--137, 1996.
2946: 
2947: \bibitem{Tho98}
2948: M.~Thorup.
2949: \newblock Faster deterministic sorting and priority queues in linear space.
2950: \newblock In {\em Proc. $9^{th}$ SODA}, pages 550--555, 1998.
2951: 
2952: \bibitem{Tho02}
2953: M.~Thorup.
2954: \newblock Equivalence between priority queues and sorting.
2955: \newblock In {\em Proc. $43^{nd}$ FOCS}, pages 125--134, 2002.
2956: 
2957: \bibitem{Tho02a}
2958: M.~Thorup.
2959: \newblock Space efficient dynamic stabbing with fast queries.
2960: \newblock In {\em Proc. $35^{th}$ STOC}, pages 649--658, 2003.
2961: 
2962: \bibitem{vB77}
2963: P.~van Emde~Boas.
2964: \newblock Preserving order in a forest in less than logarithmic time and linear
2965:   space.
2966: \newblock {\em Inf. Proc. Lett.}, 6(3):80--82, 1977.
2967: 
2968: \bibitem{vBKZ77}
2969: P.~van Emde~Boas, R.~Kaas, and E.~Zijlstra.
2970: \newblock Design and implementation of an efficient priority queue.
2971: \newblock {\em Math. Syst. Theory}, 10:99--127, 1977.
2972: 
2973: \bibitem{WillLog}
2974: D.~E. Willard.
2975: \newblock Log-logarithmic worst-case range queries are possible in space
2976:   $\theta(n)$.
2977: \newblock {\em Inf. Proc. Lett.}, 17:81--84, 1983.
2978: 
2979: \bibitem{Wil00}
2980: D.~E. Willard.
2981: \newblock Examining computational geometry, van {E}mde {B}oas trees, and
2982:   hashing from the perspective of the fusion tree.
2983: \newblock {\em SIAM J. Comput.}, 29(3):1030--1049, 2000.
2984: \newblock Announced at SODA'92.
2985: 
2986: \bibitem{WL85}
2987: D.~E. Willard and G.~S. Lueker.
2988: \newblock Adding range restriction capability to dynamic data structures.
2989: \newblock {\em J. ACM}, 32(3):597--617, 1985.
2990: 
2991: \end{thebibliography}
2992: 
2993: \end{document}
2994: 
2995: