Sum of nodes in the path from root to N-th node in given Tree
Last Updated :
24 Apr, 2023
Given an integer N which needs to be present as a value in a node in the last level of a Tree rooted at 1 having nodes numbered from root to the last level by increments of 1. The nodes at every odd level contain 2 children and nodes at every even level contains 4 children. The task is to find the sum of node values in the path from the root to the node N.
Examples:
Input: N = 13
Output: 20
Explanation: The traversal from root 1 to node 13 is 1 -> 2 -> 4 -> 13. Therefore, sum of all nodes in the path = 1 + 2 + 4 + 13 = 20.
Input: N = 124
Output: 193
Explanation: The traversal from root 1 to node 124 is 1 -> 2 -> 6 -> 16 -> 44 -> 124. Therefore, sum of all nodes in the path = 1 + 2 + 6 + 16 + 44 + 124 = 193.
Approach: Follow the steps below to solve the problem:
- Initialize an array to store the number of nodes present in each level of the Tree, i.e. {1, 2, 8, 16, 64, 128 ….} and store it.
- Calculate prefix sum of the array i.e. {1 3 11 27 91 219 …….}
- Find the index ind in the prefix sum array which exceeds or is equal to N using lower_bound(). Therefore, ind indicates the number of levels that need to be traversed to reach node N.
- Initialize a variable temp = N and two variables final_ans = 0 and val.
- Decrement ind until it is less than or equal to 1 and keep updating val = temp – prefix[ind – 1].
- Update temp to prefix[ind – 2] + (val + 1) / 2 if ind is odd.
- Otherwise, update prefix[ind – 2] + (val + 3) / 4 if ind is even.
- After completing the above steps, add N + 1 to final_ans and print it as the required answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll sumOfPathNodes(ll N)
{
if (N == 1) {
return 1;
}
else if (N == 2 || N == 3) {
return N + 1;
}
vector<ll> arr;
arr.push_back(1);
ll k = 1;
bool flag = true ;
while (k < N) {
if (flag == true ) {
k *= 2;
flag = false ;
}
else {
k *= 4;
flag = true ;
}
if (k > N) {
break ;
}
arr.push_back(k);
}
ll len = arr.size();
vector<ll> prefix(len);
prefix[0] = 1;
for (ll i = 1; i < len; ++i) {
prefix[i] = arr[i] + prefix[i - 1];
}
vector<ll>::iterator it
= lower_bound(prefix.begin(),
prefix.end(), N);
ll ind = it - prefix.begin();
ll final_ans = 0;
ll temp = N;
while (ind > 1) {
ll val = temp - prefix[ind - 1];
if (ind % 2 != 0) {
temp = prefix[ind - 2]
+ (val + 1) / 2;
}
else {
temp = prefix[ind - 2]
+ (val + 3) / 4;
}
--ind;
final_ans += temp;
}
final_ans += (N + 1);
return final_ans;
}
int main()
{
ll N = 13;
cout << sumOfPathNodes(N) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG{
static int sumOfPathNodes( int N)
{
if (N == 1 )
{
return 1 ;
}
else if (N == 2 ||
N == 3 )
{
return N + 1 ;
}
Vector<Integer> arr =
new Vector<>();
arr.add( 1 );
int k = 1 ;
boolean flag = true ;
while (k < N)
{
if (flag == true )
{
k *= 2 ;
flag = false ;
}
else
{
k *= 4 ;
flag = true ;
}
if (k > N)
{
break ;
}
arr.add(k);
}
int len = arr.size();
int [] prefix = new int [len];
prefix[ 0 ] = 1 ;
for ( int i = 1 ; i < len; ++i)
{
prefix[i] = arr.get(i) +
prefix[i - 1 ];
}
int it = lowerBound(prefix, 0 ,
len, N) + 1 ;
int ind = it - prefix[ 0 ];
int final_ans = 0 ;
int temp = N;
while (ind > 1 )
{
int val = temp -
prefix[ind - 1 ];
if (ind % 2 != 0 )
{
temp = prefix[ind - 2 ] +
(val + 1 ) / 2 ;
}
else
{
temp = prefix[ind - 2 ] +
(val + 3 ) / 4 ;
}
--ind;
final_ans += temp;
}
final_ans += (N + 1 );
return final_ans;
}
static int lowerBound( int [] a, int low,
int high, int element)
{
while (low < high)
{
int middle = low +
(high - low) / 2 ;
if (element > a[middle])
low = middle + 1 ;
else
high = middle;
}
return low;
}
public static void main(String[] args)
{
int N = 13 ;
System.out.print(
sumOfPathNodes(N) + "\n" );
}
}
|
Python3
from bisect import bisect_left, bisect
def sumOfPathNodes(N):
if (N = = 1 ):
return 1
elif (N = = 2 or N = = 3 ):
return N + 1
arr = []
arr.append( 1 )
k = 1
flag = True
while (k < N):
if (flag = = True ):
k * = 2
flag = False
else :
k * = 4
flag = True
if (k > N):
break
arr.append(k)
lenn = len (arr)
prefix = [ 0 ] * (lenn)
prefix[ 0 ] = 1
for i in range ( 1 , lenn):
prefix[i] = arr[i] + prefix[i - 1 ]
it = bisect_left(prefix, N)
ind = it
final_ans = 0
temp = N
while (ind > 1 ):
val = temp - prefix[ind - 1 ]
if (ind % 2 ! = 0 ):
temp = prefix[ind - 2 ] + (val + 1 ) / / 2
else :
temp = prefix[ind - 2 ] + (val + 3 ) / / 4
ind - = 1
final_ans + = temp
final_ans + = (N + 1 )
return final_ans
if __name__ = = '__main__' :
N = 13
print (sumOfPathNodes(N))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int sumOfPathNodes( int N)
{
if (N == 1)
{
return 1;
}
else if (N == 2 ||
N == 3)
{
return N + 1;
}
List< int > arr = new List< int >();
arr.Add(1);
int k = 1;
bool flag = true ;
while (k < N)
{
if (flag == true )
{
k *= 2;
flag = false ;
}
else
{
k *= 4;
flag = true ;
}
if (k > N)
{
break ;
}
arr.Add(k);
}
int len = arr.Count;
int [] prefix = new int [len];
prefix[0] = 1;
for ( int i = 1; i < len; ++i)
{
prefix[i] = arr[i] +
prefix[i - 1];
}
int it = lowerBound(prefix, 0,
len, N) + 1;
int ind = it - prefix[0];
int final_ans = 0;
int temp = N;
while (ind > 1)
{
int val = temp -
prefix[ind - 1];
if (ind % 2 != 0)
{
temp = prefix[ind - 2] +
(val + 1) / 2;
}
else
{
temp = prefix[ind - 2] +
(val + 3) / 4;
}
--ind;
final_ans += temp;
}
final_ans += (N + 1);
return final_ans;
}
static int lowerBound( int [] a, int low,
int high, int element)
{
while (low < high)
{
int middle = low +
(high - low) / 2;
if (element > a[middle])
low = middle + 1;
else
high = middle;
}
return low;
}
public static void Main(String[] args)
{
int N = 13;
Console.Write(sumOfPathNodes(N) + "\n" );
}
}
|
Javascript
<script>
function sumOfPathNodes(N)
{
if (N == 1)
{
return 1;
}
else if (N == 2 ||
N == 3)
{
return N + 1;
}
let arr = [];
arr.push(1);
let k = 1;
let flag = true ;
while (k < N)
{
if (flag == true )
{
k *= 2;
flag = false ;
}
else
{
k *= 4;
flag = true ;
}
if (k > N)
{
break ;
}
arr.push(k);
}
let len = arr.length;
let prefix = new Array(len);
prefix[0] = 1;
for (let i = 1; i < len; ++i)
{
prefix[i] = arr[i] + prefix[i - 1];
}
let it = lowerBound(prefix, 0, len, N) + 1;
let ind = it - prefix[0];
let final_ans = 0;
let temp = N;
while (ind > 1)
{
let val = temp - prefix[ind - 1];
if (ind % 2 != 0)
{
temp = prefix[ind - 2] +
parseInt((val + 1) / 2, 10);
}
else
{
temp = prefix[ind - 2] +
parseInt((val + 3) / 4, 10);
}
--ind;
final_ans += temp;
}
final_ans += (N + 1);
return final_ans;
}
function lowerBound(a, low, high, element)
{
while (low < high)
{
let middle = low +
parseInt((high - low) / 2, 10);
if (element > a[middle])
low = middle + 1;
else
high = middle;
}
return low;
}
let N = 13;
document.write(sumOfPathNodes(N) + "</br>" );
</script>
|
Time Complexity: O(log N)
Auxiliary Space: O(log N)
Share your thoughts in the comments
Please Login to comment...