Recurrence relationship - divide-and-conquer

Can anyone help in solving the recurrence relationship of a divide and conquer algorithm with the following equation? I am pretty sure you can't use master theorem here because it is not in the form T(n/b) but may be forgetting a simple math rule here. Please help.
T(n)=T(√n)+logn.

Notice that for some k>0 we have
T(n) = log n + log n^{1/2} + log n^{1/4} + ... + log n^{1/2^k} =
= log n + (1/2)*log n + (1/4)*log n + ... + (1/k) * log n
= (1 + 1/2 + 1/4 + ... + 1/2*k) log n
= (1 + 2^{-1} + 2^{-2} + ... + 2^{-k})log n
<= 2 log n
from which it follows that T(n) = O(log n). The bound <= 2 log n follows because 1+1/2+1/4+1/8+1/16+...=2 in the limit.

Related

What is the time complexity of inserting elements of an array into a map? [duplicate]

This question already has answers here:
Is log(n!) = Θ(n·log(n))?
(10 answers)
Closed 3 years ago.
If inserting an element takes log(N) time in a map, where N is the size of the map.
Then inserting elements of the array one by one means
log(1)+log(2)+....+log(N) = log(N!) complexity. But the normal best complexity for getting the elements sorted is Nlog(N), Where am I going wrong?
Nowhere, O(log n!) == O(n log n). The proof is a bit of math.
First, we have log(n!) = log(1) + log(2) + ... + log(n) <= log(n) + log(n) + ... + log(n) = n log(n). On the other hand, we also get the following
2 log(n!) = 2*(log(1) + log(2) + ... + log(n))
= (log(1) + log(n)) + (log(2) + log(n-1)) + ... + (log(i) + log(n-i+1)) + ... + (log(n) + log(1))
= log(1*n) + log(2*(n-1)) + ... + log(i*(n-i+1)) + ... log(n*1)
>= log(n) + ... + log(n) = n log(n)
Where we get the inequality since i*(n-i+1) = i*n - i*i + i >= n (seems a bit mysterious but it basically says that products grow faster than sums).
So we have log(n!) <= n log(n) <= 2 log(n!). By the defintion of the O-notation this means that O(log(n!)) = O(n log(n)).

Big O Notation Calculation

I'm stuck determining the big o notation for the below fragmented code, the given expression is part of I'm trying to figure out. I know given two plain, default for loops results in O(n^2) but the latter is entirely different. Here are the instructions.
The algorithm of
for (j = 0; j < n; j++)
{
for (k = j; k < n; k++)
{
}
}
will result in a number of iterations of given by the expression:
= n + (n-1) + (n-2) + (n-3) + ........ + (n - n)
Reduce the above series expression to an algebraic expression, without summation.
After determining the algebraic expression express the performance in Big O Notation.
You can use this method (supposedly applied by Gauss when he was a wee lad).
If you sum all the numbers twice, you have
1 + 2 + 3 + ... + n
+ n + (n-1) + (n-2) + ... + 1
—————————————————————————————————————--
(n+1) + (n+1) + (n+1) + ... + (n+1) = n(n+1)
Thus,
1 + 2 + 3 + ... + n = n(n+1)/2
and n(n+1)/2 is (n^2)/2 + n/2, so it is in O(n^2).

Big-O complexity of this algorithm

CODE:
void fun(int n){
if(n>2){
for(int i=0;i<n;i++){
j=0;
while(j<n){
cout<<j;
j++;
}
}
fun(n/2);
}
}
Here's what I think:
The recursive part is running log(n) times ?
and during each recursive call, the for loop will run n^2 times, with n changing to half in each recursive call.
So is it n^2 + (n^2)/4 + (n^2)/16 + ... + 1?
You are right, so the big(O) is n^2 since the sum of the series n^2 + (n^2)/4 + (n^2)/16 + ... + 1 never exceeds 2n^2
The number of writes to cout is given by the following recurrence:
T(N) = N² + T(N/2).
By educated guess, T(N) can be a quadratic polynomial. Hence
T(N) = aN²+bN+c = N² + T(N/2) = N² + aN²/4+bN/2+c.
By identification, we have
3a/4 = 1
b/2 = 0
c = c.
and
T(N) = 4N²/3 + c.
With T(2)= 0,
T(N) = 4(N²-4)/3
which is obviously O(N²).
This is simple mathematics. The complexity is n^2 + (n^2)/4 + (n^2)/16 + ... + 1. It is (n² * (1 + 1/4+ ...)) . And the maths says that the infinite serie converges to 4/3 (the formula is: 1 / (1 - 1/4)).
It gives actually O(n2).

Calculate modulus for large numbers

Hi I need to calculate (2^n + (-1)^n) % 10000007
where 1 < n < 10^9
How should I go about writing a program for it in c++?
I know this mod property
(a + b)%n = (a%n + b%n)%n but this wont help me.
Given
(a + b)%m = (a%m + b%m)%m
Then, replace both a and b with the same power of 2, and you get the recurrence:
2k+1%m = (2k%m + 2k%m)%m
You probably already figured your formula allows you to break down your problem into:
(2n + (-1)n)%P = (2n%P + (-1)n%P)%P
Then, note that (-1)k is either 1 or -1, and you should be able to calculate your problem in O(n) time.

Properties of the modulo operation

I have the compute the sum S = (a*x + b*y + c) % N. Yes it looks like a quadratic equation but it is not because the x and y have some properties and have to be calculated using some recurrence relations. Because the sum exceeds even the limits of unsigned long long I want to know how could I compute that sum using the properties of the modulo operation, properties that allow the writing of the sum something like that(I say something because I do not remember exactly how are those properties): (a*x)%N + (b*y)%N + c%N, thus avoiding exceeding the limits of unsigned long long.
Thanks in advance for your concern! :)
a % N = x means that for some integers 0 <= x < N and m: m * N + x = a.
You can simply deduce then that if a % N = x and b % N = y then
(a + b) % N =
= (m * N + x + l * N + y) % N =
= ((m + l) * N + x + y) % N =
= (x + y) % N =
= (a % N + b % N) % N.
We know that 0 < x + y < 2N, that is why you need to keep remainder calculation. This shows that it is okay to split the summation and calculate the remainders separately and then add them, but don't forget to get the remainder for the sum.
For multiplication:
(a * b) % N =
= ((m * N + x) * (l * N + y)) % N =
= ((m * l + x * l + m * y) * N + x * y) % N =
= (x * y) % N =
= ((a % N) * (b % N)) % N.
Thus you can also do the same with products.
These properties can be simply derived in a more general setting using some abstract algebra (the remainders form a factor ring Z/nZ).
You can take the idea even further, if needed:
S = ( (a%N)*(x%N)+(b%N)*(y%N)+c%N )%N
You can apply the modulus to each term of the sum as you've suggested; but even so after summing them you must apply the modulus again to get your final result.
How about this:
int x = (7 + 7 + 7) % 10;
int y = (7 % 10 + 7 % 10 + 7 % 10) % 10;
You remember right. The equation you gave, where you %N every of the summands is correct. And that would be exactly what I use. You should also %N for every partial sum (and the total) again, as the addition results can be still greater than N. BUT be careful this works only if your size limit is at least twice as big as your N. If this is not the case, it can get really nasty.
Btw for the following %N operations of the partial sums, you dont have to perform a complete division, a check > N and if bigger just subtraction of N is enough.
Not only can you reduce all variable mod n before starting the calculation, you can write your own mod-mul to compute a*x mod n by using a shift-and-add method and reduce the result mod n at each step. That way your intermediate calculations will only require one more bit than n. Once these products are computed, you can add them pairwise and reduce mod n after each addition which will also not require more than 1 bit beyond the range of n.
There is a python implementation of modular multiplication in my answer to this question. Conversion to C should be trivial.