完全二叉树的权值

本文最后更新于:19 分钟前

[蓝桥杯 2019 省 AB] 完全二叉树的权值

题目描述

给定一棵包含 N 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是 A1,A2,…An,如下图所示:

现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。

注:根的深度是1。

输入格式

第一行包含一个整数 N。

第二行包含 N 个整数 A1,A2,…An。

输出格式

输出一个整数代表答案。

样例 #1

样例输入 #1

1
2
7
1 6 5 4 3 2 1

样例输出 #1

1
2

提示

对于所有评测用例,1<=n<=1e5,0<=|Ai|<=1e5。

理解

注意到图中左边,1,2,4,都是二的倍数,每一次循环从每一层从左往右加,找出最大的并保存。

代码

60分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include<cstdio>
#include <sstream>
#include<algorithm>
#include<cmath>
#include<string>
using namespace std;
int n;
const int N=1e5+10;
int arr[N];
int main()
{

cin>>n;
for(int i=1;i<=n;i++)
{
cin>>arr[i];
}
int root=1,res=1;
long long MAX=arr[1];
for(int i=2;i<=n;)
{
int t=i;
long long sum=0;
root++;
while(i<2*t)
{
sum+=arr[i];
i++;

}
if(MAX<=sum)
{
MAX=sum;
res=root;

}

}
cout<<res<<endl;

return 0;
}

优化

想到用前缀和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
typedef long long ll;
int main(void)
{
int n; cin>>n;
ll max=-9999999,max_d=0;
for(int i=0,length=1,depth=1;i<n;depth++,length*=2)
{
ll s=0;
for(int j=0;j<length&&i<n;j++,i++)
{
int x;
cin>>x;
s+=x;
}
if(s>max)
{
max=s;
max_d=depth;
}
}
cout<<max_d<<endl;
return 0;
}


完全二叉树的权值
http://example.com/2023/04/24/完全二叉树的权值/
作者
zzh
发布于
2023年4月24日
更新于
2023年4月24日
许可协议
原文链接: HTTPS://ZHANGZHIHAO-BLOG.GITHUB.IO
版权声明: 转载请注明出处!