给定一个整数N ,它需要作为一个值出现在以1为根的树的最后一级中的节点中,该树的节点编号从根到最后一级,增量为1 。每个奇数级别的节点包含2 个子节点,每个偶数级别的节点包含4 个子节点。任务是在从根到节点N的路径中找到节点值的总和。
例子:
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.
处理方法:按照以下步骤解决问题:
- 初始化一个数组来存储树的每一层中存在的节点数,即{1, 2, 8, 16, 64, 128 ….}并存储它。
- 计算数组的前缀和,即{1 3 11 27 91 219 …….}
- 使用lower_bound() 在前缀和数组中找到超过或等于N的索引ind 。因此, ind表示到达节点N需要遍历的层数。
- 初始化一个变量temp = N和两个变量final_ans = 0和val 。
- 递减ind直到它小于或等于1并不断更新val = temp – prefix[ind – 1] 。
- 如果ind为奇数,则将temp更新为prefix[ind – 2] + (val + 1) / 2 。
- 否则,如果ind为偶数,则更新prefix[ind – 2] + (val + 3) / 4 。
- 完成以上步骤后,在final_ans中加N+1 ,pint为必选答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
typedef long long ll;
// Function to find sum of all
// nodes from root to N
ll 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 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 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::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 Code
int main()
{
ll N = 13;
// Function Call
cout << sumOfPathNodes(N) << endl;
return 0;
}
Java
// Java program for the
// above approach
import java.util.*;
class GFG{
// Function to find sum of
// aint nodes from root to N
static 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 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 Code
public 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 approach
from bisect import bisect_left, bisect
# Function to find sum of all
# nodes from root to N
def 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 leve 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 Code
if __name__ == '__main__':
N = 13
# Function Call
print(sumOfPathNodes(N))
# This code is contributed by mohit kumar 29
C#
// C# program for the
// above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find sum of
// aint nodes from root to N
static 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 arr = new List();
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 Code
public static void Main(String[] args)
{
int N = 13;
// Function Call
Console.Write(sumOfPathNodes(N) + "\n");
}
}
// This code is contributed by Amit Katiyar
输出:
20
时间复杂度: O(log N)
辅助空间: O(log N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live