This solution is courtesy of George Ruban 10-14-1994

Efficient CRCW PRAM algorithm for finding maximum of N numbers 

   Suggest an O(log(log n)) CRCW PRAM algorithm to compute the maximum of
   N numbers using no more than O(N) processors.

Assign one number and one comparison to each processor.
It takes (n choose 2) comparisons to compare n numbers, so that each
number is compared against every other one.  This is n! / (2 * (n-2)!).
In each comparison, the processor representing the lesser number gets sent
a message, such as "deactivate, you lost" (choose randomly if the compared nos
equal).  It is still around to do more computations, though.  It might get
more than one of these messages, but it will only get this message, if any,
so the CW paradigm is satisfied.

For the first step in the algorithm, we have n processors available, so
group the processors into groups of 3.  Since 3! / (2 * 1) =  3, there are
enough processors available to completely compare the numbers in each group
against each other. Exactly 2 of each group will lose, so for the next
step, there are only n/3 numbers to be compared, but n processors to
compare.  Let m = n/3.  Solve 3m = m! / (2* (m-2)!) to get the size of the
next group.  6m = m * (m-1) ->	6 = m-1 -> m=7.  So assign 21 processors to
compare 7 numbers completely, in the sense that this will eliminate 6 of
each group.  In two steps, only 1/ (7*3) = 1/21 of the numbers are still
contenders.  For the next step, there are 21 times as many processors
available as numbers to compare, so 21m = m! / (2 * (m-2)!) -> m = 43.
The next step, 3 * 7 * 43 m = m! / (2* (m-2)!) -> gets ridiculous quickly.

I am leaving out the details of how each group of 21 processors knows which
7 numbers it has to deal with, and even how to distribute the comparisons
amongst the processors, but it should be clear that there some math-heavy
but logically simple algorithm for how to solve this in 0(1).

With each step we eliminate all but one number from each group.  When the
size of the group grows to be n, we will be done.   

How fast does this grow? Each time we are solving for m(k) the equation
(Product of all previous m's, to k-1) * m(k) = m(k)! / (2 * (m(k)-2)!)
2 * (Product) * m(k) = m(k) * (m(k)-1)
m(k) = 2 * (Product) + 1
Let's forget about the +1, and unroll this a bit.
m(k) >= 2 * m(k-1) * m(k-2) * (Product up to k-3)
But m(k-1) >= 2 * m(k-2) * (Product up to k-3), so:
m(k) >= m(k-2) ^2 (squared) * 4 * (Product up to k-3) ^2
m(k) >= m(k-2) ^2
So this function clearly more than squares itself every 2 steps.
We are done when m(k) = n.
Let's play with an easier function that squares itself every step - it
obviously does not grow more than a constant amount faster - and see how
many steps it takes it to grow to size n.
f(k) = 2 ^ (2 ^ k)
n = 2 ^ (2 ^ k)
lg n = 2 ^ k
lg lg n = k.
So this algorithm is _at_most_ O(lg lg n) in terms of time - and it may be
even better, because I dropped off what may be significant terms, the
4*(Product up to k-3)

   What is the best EREW PRAM algorithm you can come up with to compute the
   maximum of N numbers using no more than O(N) processors?

You can't beat O(lg n).  Unlike the previous problem, only one processor
may be at work on a number, because the number may only be eliminated by
one processor at a time.  Build a tree and compare.  While you are at it,
you may as well sort the whole array!

Hint: First, think about an efficient algorithm to find the maximum of n
numbers using no more than O(n^2) processors, and then reduce the original
problem to that one.