Начните с внутренних циклов:
k := 2;
while n >= k do
k := k * k
Это присваивает значения 2, 2 2 , 2 4 , 2 8 , ... до k
, пока не достигнет п
. Это O (log (log (n)), потому что, если мы будем называть число итераций m, оно повторяется до
22m > n → log(22m) > log(n) → log(log(22m)) > log(log(n)) →
→ m > log(log(n)) → m = log(log(n)) + 1
затем
for j:= i div 2 + 1 to i do
begin
//O(log(log(n))
end;
Это имеет i/2 итерации, поэтому O ((i/2) log (log (n)))
i := n;
while i > 1 do
begin
//(i/2) log(log(n))
i := i div 2
end;
Это имеет O (log (n)) итераций O ((i/2) log (log (n))), который суммируется с
O( (n/2) log(log(n)) + (n/4) log(log(n)) + (n/8) log(log(n)) + (n/16) log(log(n)) + ... ) =
= O( (1/2 + 1/4 + 1/8 + 1/16 + ...) n log(log(n)) ) =
= O( 0.1111111…2 n log(log(n)) ) =
= O( n log(log(n)) )
(0.11111 ... 2 = 1, как и 0.999 ... 10 = 1, но это не имеет значения в O() в любом случае)