一、题目链接
二、题目分析
(一)算法标签
双指针 二叉树
(二)解题思路
含n个结点的满二叉树的深度为 ⌊ l o g 2 n ⌋ + 1 \lfloor log_{2}{n} \rfloor + 1 ⌊log2n⌋+1 或 ⌈ l o g 2 ( n + 1 ) ⌉ \lceil log_{2}{(n+1)} \rceil ⌈log2(n+1)⌉
cout << (int)(log(1e5) / log(2)) + 1 << endl;
cout << -pow(2, 16) * 1e5;
// output:
17
-6.5536e+09
含有
1
0
5
10^5
105 个结点对应的满二叉树的深度为17, 每一层最多有
2
n
−
1
2^{n-1}
2n−1 个结点,因此结点之和最小为
2
n
−
1
×
(
−
1
0
5
)
=
−
6.5536
×
1
0
9
2^{n - 1} \times {(-10^{5})} = -6.5536 \times 10^9
2n−1×(−105)=−6.5536×109 比 INT_MIN (2147483647)还要小,所以要sum为long long类型
思路:
遍历每一层,计算每一层的和,如果大于当前的sum,则更新maxSum,同时更新答案为当前层数下标
三、AC代码
解法一:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <climits>
#include <cmath>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int a[N];
int n;
int main()
{
cin >> n;
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
LL maxSum = -1e18;
int res;
for (int i = 1; i <= (int)(log(n) / log(2)) + 1; i ++ ) // n 个 结点的二叉树的深度为log(n + 1)/log(2) + 1 (向上取整)
{
LL sum = 0;
for (int j = pow(2, i - 1); j <= pow(2, i) - 1 && j <= n; j ++ ) // 题目数据不是满二叉树,因此要判断j是否小于n
sum += a[j];
if (sum > maxSum)
{
maxSum = sum;
res = i;
}
}
cout << res << endl;
// cout << log(1e5) / log(2) + 1 << endl;
// cout << -pow(2, 17) * 1e5;
return 0;
}