\documentclass[11pt]{article}

\usepackage{epsfig}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{amstext}
\usepackage{amsmath}
\usepackage{xspace}
\usepackage{theorem}
\usepackage{hyperref}
\usepackage{fullpage}
\usepackage{algorithm}
\usepackage{algpseudocode}
\usepackage{framed}
\usepackage{enumitem}      
\usepackage{listings}
               

\newif\ifrubric
\rubrictrue
%\rubricfalse

% This is the stuff for normal spacing
%\makeatletter
% \setlength{\textwidth}{6.5in}
% \setlength{\oddsidemargin}{0in}
% \setlength{\evensidemargin}{0in}
% \setlength{\topmargin}{0.25in}
% \setlength{\textheight}{8.25in}
% \setlength{\headheight}{0pt}
% \setlength{\headsep}{0pt}
% \setlength{\marginparwidth}{59pt}
%
% \setlength{\parindent}{0pt}
% \setlength{\parskip}{5pt plus 1pt}
% \setlength{\theorempreskipamount}{5pt plus 1pt}
% \setlength{\theorempostskipamount}{0pt}
% \setlength{\abovedisplayskip}{8pt plus 3pt minus 6pt}
 
 
 \usepackage{titlesec}

\titleformat*{\section}{\bfseries}
\titleformat*{\subsection}{\bfseries}
\titleformat*{\subsubsection}{\bfseries}
\titleformat*{\paragraph}{\bfseries}
\titleformat*{\subparagraph}{\bfseries}

% \renewcommand{\section}{\@startsection{section}{1}{0mm}%
%                                   {2ex plus -1ex minus -.2ex}%
%                                   {1.3ex plus .2ex}%
%                                   {\normalfont\Large\bfseries}}%
% \renewcommand{\subsection}{\@startsection{subsection}{2}{0mm}%
%                                     {1ex plus -1ex minus -.2ex}%
%                                     {1ex plus .2ex}%
%                                     {\normalfont\large\bfseries}}%
% \renewcommand{\subsubsection}{\@startsection{subsubsection}{3}{0mm}%
%                                     {1ex plus -1ex minus -.2ex}%
%                                     {1ex plus .2ex}%
%                                     {\normalfont\normalsize\bfseries}}
% \renewcommand\paragraph{\@startsection{paragraph}{4}{0mm}%
%                                    {1ex \@plus1ex \@minus.2ex}%
%                                    {-1em}%
%                                    {\normalfont\normalsize\bfseries}}
% \renewcommand\subparagraph{\@startsection{subparagraph}{5}{\parindent}%
%                                       {2.0ex \@plus1ex \@minus .2ex}%
%                                       {-1em}%
%                                      {\normalfont\normalsize\bfseries}}
%\makeatother

\newenvironment{proof}{{\bf Proof:  }}{\hfill\rule{2mm}{2mm}}
\newenvironment{proofof}[1]{{\bf Proof of #1:  }}{\hfill\rule{2mm}{2mm}}
\newenvironment{proofofnobox}[1]{{\bf#1:  }}{}
\newenvironment{example}{{\bf Example:  }}{\hfill\rule{2mm}{2mm}}
%\renewcommand{\thesection}{\lecnum.\arabic{section}}

%\renewcommand{\theequation}{\thesection.\arabic{equation}}
%\renewcommand{\thefigure}{\thesection.\arabic{figure}}

%\renewcommand{\theequation}{\lecnum.\arabic{equation}}
%\renewcommand{\thefigure}{\lecnum.\arabic{figure}}

%\newcounter{LecNum}
%\setcounter{LecNum}{1}

%\newtheorem{fact}{Fact}[LecNum]
\newtheorem{fact}{Fact}
\newtheorem{lemma}[fact]{Lemma}
\newtheorem{theorem}[fact]{Theorem}
\newtheorem{definition}[fact]{Definition}
\newtheorem{corollary}[fact]{Corollary}
\newtheorem{proposition}[fact]{Proposition}
\newtheorem{claim}[fact]{Claim}
\newtheorem{exercise}[fact]{Exercise}

% math notation
\newcommand{\R}{\ensuremath{\mathbb R}}
\newcommand{\Z}{\ensuremath{\mathbb Z}}
\newcommand{\N}{\ensuremath{\mathbb N}}
\newcommand{\F}{\ensuremath{\mathcal F}}
\newcommand{\SymGrp}{\ensuremath{\mathfrak S}}

\newcommand{\size}[1]{\ensuremath{\left|#1\right|}}
\newcommand{\ceil}[1]{\ensuremath{\left\lceil#1\right\rceil}}
\newcommand{\floor}[1]{\ensuremath{\left\lfloor#1\right\rfloor}}
\newcommand{\poly}{\operatorname{poly}}
\newcommand{\polylog}{\operatorname{polylog}}

% anupam's abbreviations
\newcommand{\e}{\epsilon}
\newcommand{\half}{\ensuremath{\frac{1}{2}}}
\newcommand{\junk}[1]{}
\newcommand{\sse}{\subseteq}
\newcommand{\union}{\cup}
\newcommand{\meet}{\wedge}

\newcommand{\prob}[1]{\ensuremath{\text{{\bf Pr}$\left[#1\right]$}}}
\newcommand{\expct}[1]{\ensuremath{\text{{\bf E}$\left[#1\right]$}}}
\newcommand{\Event}{{\mathcal E}}

\newcommand{\mnote}[1]{\normalmarginpar \marginpar{\tiny #1}}

\setenumerate[0]{label=(\alph*)}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Document begins here %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



\begin{document}

\noindent {\large {\bf 601.433/633 Introduction to Algorithms} \hfill {{\bf Fall 2024}}}\\
{{\bf Homework \#3}} \hfill {{\bf Due:} September 24, 2024, 9am} \\
\rule[0.1in]{\textwidth}{0.4pt}

Remember: you may work in groups of up to three people, but must write up your solution entirely on your own.  Collaboration is limited to discussing the problems -- you may not look at, compare, reuse, etc.~any text from anyone else in the class.  Please include your list of collaborators on the first page of your submission.  You may use the internet to look up formulas, definitions, etc., but may not simply look up the answers online.  

Please include proofs with all of your answers, unless stated otherwise.

\noindent \rule[0.1in]{\textwidth}{0.4pt}


\section{Group Sorting (67 points)}
We say that an array $A$ of size $n$ is \emph{$k$-group sorted} if it can be divided into $k$ consecutive groups, each of size $n/k$, such that the elements in each group are larger than the elements in earlier groups, and smaller than elements in later groups. The elements within each group need not be sorted.   

For example, the following array is $4$-group sorted:
\[
\begin{array}{|c|c|c|c||c|c|c|c||c|c|c|c||c|c|c|c|}
\hline
1 &2 &4 &3 &7 &6 &8 &5 &10 &11 &9 &12 &15 &13 &16 &14\\
\hline
\end{array}
\]

Note that every array is $1$-group-sorted, and only sorted arrays are $n$-group sorted.  For the rest of this problem we will only care about deterministic algorithms (and lower bounds against deterministic algorithms).  You may assume that all elements are distinct, and if you want to you may assume that $n$ and $k$ are powers of $2$. 

\begin{enumerate}
\item (17 points) Describe an algorithm that $k$-group-sorts an array in $O(n \log k)$ (i.e., in at most $O(n \log k)$ time it must turn an array which is not $k$-group sorted into one that is).  Prove correctness and running time.

\item (17 points) Prove that any comparison-based $k$-group-sorting algorithm requires $\Omega(n \log k)$ comparisons in the worst case.   

\item (16 points) Describe an algorithm that completely sorts an already $k$-group-sorted array in $O(n \log(n/k))$ time.  Prove correctness and running time.

\item (17 points) Prove that any comparison-based algorithm to completely sort an already $k$-group-sorted array requires $\Omega(n \log(n/k))$ comparisons in the worst case.  

\end{enumerate}
 

\section{Range Queries (33 points)}
We saw in class how to use binary search trees as dictionaries, and in particular how to use them to do $insert$ and $lookup$ operations.  Some of you might naturally wonder why we bother to do this, when hash tables (which we will talk about later) already allow us to do this.  While there are many good reasons to use search trees rather than hash tables, one informal reason is that search trees can in some cases be either used directly or easily extended to allow efficient queries that are difficult or impossible to do efficiently in a hash table.  

An important example of this is a \emph{range query}.  Suppose that all keys are distinct.  In addition to being able to insert and lookup (and possibly delete), we want to allow a new operation \emph{range($x,y$)} which is supposed to return the number of keys in the tree which are at least $x$ and at most $y$.

In this problem we will only be concerned with normal binary search trees (nothing fancy like B-trees, red-black trees, AVL trees, etc.).  Recall that in binary search trees of height $h$, inserts can be done in $O(h)$ time.  For all of the parts, prove both correctness and running time.

\begin{enumerate}
\item (11 points) Given a binary search tree of height $h$, show how to implement \emph{range($x,y$)} in $O(h + k)$ time, where $k$ is the number of elements that are at least $x$ and at most $y$.

\end{enumerate}

Can we do this operation even faster?  It turns out that we can!  In particular, for a binary search tree of height $h$, we can do this in $O(h)$ time.  We will prove this in the rest of the problem.
\begin{enumerate}[resume]
\item (11 points) Describe an extra piece of information that you will store at each node of the tree, and describe how to use this extra information to do the above range query in $O(h)$ time.  

Hint: think of keeping track of a size.

\item (11 points) Describe how to maintain this information in $O(h)$ time when a new node is inserted (note that there are no rotations on an insert -- it's just the regular binary search tree insert, but you need to update information appropriately).  

\end{enumerate}



\end{document}



































