注意用long long
法1:按数的序号加
pow在c的math头文件里,所以在c++的cmath
非常注意内部按数的序号加每层权值和时,一定要添加i<=n啊,因为这是完全二叉树,不是满二叉树,最后一层可能缺胳膊少腿的
完整代码:
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
ll a[100010];
int main(){
int mindeep=1,n;
cin>>n>>a[1];
for(int i=2;i<=n;i++){
cin>>a[i];
}
ll max=a[1];
int i=2,deep=2;
while(i<=n){
ll sum=0;
for(;i<=n&&i<=pow(2,deep)-1;i++)//因为我少些了i<=n而错啊啊啊啊啊
{
sum+=a[i];
}
if(sum>max){
max=sum;mindeep=deep;
}
deep++;
}
cout<<mindeep;
return 0;
}
法2:按层加
引入sum[]数组来记录第几层的权值和
求序号在二叉树的第几层,就是用它除以2,能除几次在第几层,其实就是log2(x),但是直接用log函数可能有问题
x>>=1即左移两位,等价于x=x>>1; 或者x=x/2;
这里有三种求最大权值和的最浅层数,13同理,只有23是对的
1 while(deep--){//从最底层往上走,求得的一定是深度最小的
if(max<=sum[deep]){
max=sum[deep];
mindeep=deep;
}
}
2 for(int i=2;i<=deep;i++){
if(max<sum[i])
{
max=sum[i];
mindeep=i;
}
}
3 for(int i=deep;i>=1;i--){//从最底层往上走,求得的一定是深度最小的
//记得要包含i=1
if(max<=sum[i]){
max=sum[i];
mindeep=i;
}
}
完整代码:
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
ll a[100010];
ll sum[100];//sum[i]为第i层的权值和
int deeplog(ll x){//能求出序号x在二叉树的第几层
int deep=0;
while(x){
x>>=1;
deep++;
}
return deep;
}
int main(){
int n;
cin>>n;
ll deep=deeplog(n);//规定层数1~
for(int i=1;i<=n;i++){
cin>>a[i];
sum[deeplog(i)]+=a[i];
}
ll max=sum[1];int mindeep=1;
/* while(deep--){//从最底层往上走,求得的一定是深度最小的
if(max<=sum[deep]){
max=sum[deep];
mindeep=deep;
}
}*/
/* for(int i=2;i<=deep;i++){
if(max<sum[i])
{
max=sum[i];
mindeep=i;
}
}*/
for(int i=deep;i>=1;i--){//从最底层往上走,求得的一定是深度最小的
//记得要包含i=1
if(max<=sum[i]){
max=sum[i];
mindeep=i;
}
}
cout<<mindeep;
return 0;
}
再做一次出现的问题:
1单个结点的数值最大是5位数,但是最多可能有10^5个这样的数,所以还是有可能超出int范围的,说了吧对多个int类型的进行运算还是要注意这个结果的;另外如果有中间值,比如sum,当然肯定也是要用long long 的啊,这个真的很容易忘记
2while(i<=n){}部分我写成了for(int i=2;i<=n;i++),但是这样就导致再内部的while加和中i已经是下一层的第一个数的下标了,上一层算完之后因为写的这个for又被+了1,就错啦!
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int a[100010];
int main()
{
int n;cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
long long maxx=a[1];//单个结点的数值最大是5位数,但是最多可能有10^5个这样的数,所以还是有可能超出int范围的,说了吧对多个int类型的进行运算还是要注意这个结果的
int mindeep=1,deep=2,i=2;
while(i<=n)
{
long long sum=0;
int t=pow(2,deep-1);
while(t--&&i<=n)//考虑最后一层是可能不完整的
{
sum+=a[i];
i++;
}
if(sum>maxx)
{
mindeep=deep;
maxx=sum;
}
deep++;
}
cout<<mindeep<<endl;
return 0;
}