Sum of nodes in the path from root to N-th node in given Tree

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++
// C++ program for the above approach#include <bits/stdc++.h>using namespace std;typedef long long ll;Â
// Function to find sum of all// nodes from root to Nll sumOfPathNodes(ll N){Â
    // If N is equal to 1    if (N == 1) {        return 1;    }Â
    // If N is equal to 2 or 3    else if (N == 2 || N == 3) {        return N + 1;    }Â
    // Stores the number of    // nodes at (i + 1)-th level    vector<ll> arr;    arr.push_back(1);Â
    // Stores the number of nodes    ll k = 1;Â
    // Stores if the current    // level is even or odd    bool flag = true;Â
    while (k < N) {Â
        // If level is odd        if (flag == true) {            k *= 2;            flag = false;        }Â
        // If level is even        else {Â
            k *= 4;            flag = true;        }Â
        // If level with        // node N is reached        if (k > N) {            break;        }Â
        // Push into vector        arr.push_back(k);    }Â
    ll len = arr.size();    vector<ll> prefix(len);    prefix[0] = 1;Â
    // Compute prefix sums of count    // of nodes in each level    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);Â
    // Stores the level in which    // node N s present    ll ind = it - prefix.begin();Â
    // Stores the required sum    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;Â
        // Add temp to the sum        final_ans += temp;    }Â
    final_ans += (N + 1);Â
    return final_ans;}Â
// Driver Codeint main(){Â
    ll N = 13;Â
    // Function Call    cout << sumOfPathNodes(N) << endl;Â
    return 0;} |
Java
// Java program for the// above approachimport java.util.*;class GFG{Â
// Function to find sum of// all nodes from root to Nstatic int sumOfPathNodes(int N){Â Â // If N is equal to 1Â Â if (N == 1) Â Â {Â Â Â Â return 1;Â Â }Â
  // If N is equal to   // 2 or 3  else if (N == 2 ||            N == 3)   {    return N + 1;  }Â
  // Stores the number of  // nodes at (i + 1)-th level  Vector<Integer> arr =          new Vector<>();  arr.add(1);Â
  // Stores the number   // of nodes  int k = 1;Â
  // Stores if the current  // level is even or odd  boolean flag = true;Â
  while (k < N)   {    // If level is odd    if (flag == true)     {      k *= 2;      flag = false;    }Â
    // If level is even    else    {      k *= 4;      flag = true;    }Â
    // If level with    // node N is reached    if (k > N)     {      break;    }Â
    // Push into vector    arr.add(k);  }Â
  int len = arr.size();  int[] prefix = new int[len];  prefix[0] = 1;Â
  // Compute prefix sums of   // count of nodes in each  // level  for (int i = 1; i < len; ++i)  {    prefix[i] = arr.get(i) +                 prefix[i - 1];  }Â
  int it = lowerBound(prefix, 0,                       len, N) + 1;Â
  // Stores the level in which  // node N s present  int ind = it - prefix[0];Â
  // Stores the required sum  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;Â
    // Add temp to the sum    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;}Â
// Driver Codepublic static void main(String[] args){Â Â int N = 13;Â
  // Function Call  System.out.print(  sumOfPathNodes(N) + "\n");}}Â
// This code is contributed by gauravrajput1 |
Python3
# Python3 program for the above approachfrom bisect import bisect_left, bisectÂ
# Function to find sum of all# nodes from root to Ndef sumOfPathNodes(N):Â Â Â Â Â Â Â Â Â # If N is equal to 1Â Â Â Â if (N == 1):Â Â Â Â Â Â Â Â return 1Â
    # If N is equal to 2 or 3    elif (N == 2 or N == 3):        return N + 1             # Stores the number of    # nodes at (i + 1)-th level    arr = []    arr.append(1)Â
    # Stores the number of nodes    k = 1Â
    # Stores if the current    # level is even or odd    flag = True         while (k < N):                 # If level is odd        if (flag == True):            k *= 2            flag = False                     # If level is even        else:            k *= 4            flag = TrueÂ
        # If level with        # node N is reached        if (k > N):            break                 # Push into vector        arr.append(k)Â
    lenn = len(arr)    prefix = [0] * (lenn)    prefix[0] = 1         # Compute prefix sums of count    # of nodes in each level    for i in range(1, lenn):        prefix[i] = arr[i] + prefix[i - 1]             it = bisect_left(prefix, N)         # Stores the level in which    # node N s present    ind = itÂ
    # Stores the required sum    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Â
        # Add temp to the sum        final_ans += tempÂ
    final_ans += (N + 1)Â
    return final_ansÂ
# Driver Codeif __name__ == '__main__':Â Â Â Â Â Â Â Â Â N = 13Â
    # Function Call    print(sumOfPathNodes(N))Â
# This code is contributed by mohit kumar 29 |
C#
// C# program for the// above approachusing System;using System.Collections.Generic;Â
class GFG{Â
// Function to find sum of// all nodes from root to Nstatic int sumOfPathNodes(int N){Â Â Â Â Â // If N is equal to 1Â Â if (N == 1) Â Â {Â Â Â Â return 1;Â Â }Â
  // If N is equal to   // 2 or 3  else if (N == 2 ||            N == 3)   {    return N + 1;  }Â
  // Stores the number of  // nodes at (i + 1)-th level  List<int> arr = new List<int>();  arr.Add(1);Â
  // Stores the number   // of nodes  int k = 1;Â
  // Stores if the current  // level is even or odd  bool flag = true;Â
  while (k < N)   {         // If level is odd    if (flag == true)     {      k *= 2;      flag = false;    }Â
    // If level is even    else    {      k *= 4;      flag = true;    }Â
    // If level with    // node N is reached    if (k > N)     {      break;    }Â
    // Push into vector    arr.Add(k);  }Â
  int len = arr.Count;  int[] prefix = new int[len];  prefix[0] = 1;Â
  // Compute prefix sums of   // count of nodes in each  // level  for(int i = 1; i < len; ++i)  {    prefix[i] = arr[i] +                 prefix[i - 1];  }Â
  int it = lowerBound(prefix, 0,                       len, N) + 1;     // Stores the level in which  // node N s present  int ind = it - prefix[0];Â
  // Stores the required sum  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;         // Add temp to the sum    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;}Â
// Driver Codepublic static void Main(String[] args){  int N = 13;     // Function Call  Console.Write(sumOfPathNodes(N) + "\n");}}Â
// This code is contributed by Amit Katiyar |
Javascript
<script>Â
// Javascript program for the above approachÂ
// Function to find sum of// all nodes from root to Nfunction sumOfPathNodes(N){         // If N is equal to 1    if (N == 1)    {        return 1;    }         // If N is equal to    // 2 or 3    else if (N == 2 ||             N == 3)    {        return N + 1;    }         // Stores the number of    // nodes at (i + 1)-th level    let arr = [];    arr.push(1);         // Stores the number    // of nodes    let k = 1;         // Stores if the current    // level is even or odd    let flag = true;         while (k < N)    {                 // If level is odd        if (flag == true)        {            k *= 2;            flag = false;        }                 // If level is even        else        {            k *= 4;            flag = true;        }                 // If level with        // node N is reached        if (k > N)        {            break;        }                 // Push into vector        arr.push(k);    }         let len = arr.length;    let prefix = new Array(len);    prefix[0] = 1;         // Compute prefix sums of    // count of nodes in each    // level    for (let i = 1; i < len; ++i)    {        prefix[i] = arr[i] + prefix[i - 1];    }         let it = lowerBound(prefix, 0, len, N) + 1;         // Stores the level in which    // node N s present    let ind = it - prefix[0];         // Stores the required sum    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;                 // Add temp to the sum        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;}Â
// Driver codelet N = 13;Â
// Function Calldocument.write(sumOfPathNodes(N) + "</br>");Â
// This code is contributed by divyeshrabadiya07Â
</script> |
20
Â
Time Complexity: O(log N)Â
Auxiliary Space: O(log N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!




