D-和谐之树:求线段树的最大节点

易知,线段树是完全二叉树,最大节点在最深层的最右边,所以要找最深且最右;

二分来找,判断标准是查看每个节点的左子树和右子树谁的深度大,如果一样就走右。(最深->最右)

查找深度,很神奇

由于线段树的性质,可以已知区间长度,通过模拟建造二叉树的方式得到高度,即深度。

1 ll count(ll x){//区间长度
2     ll t=1;
3     while(x>1){
4         x=(x+1)/2;//不断合并向上
5         t++;//高度++
6     }
7     return t;
8 }

由此易得:

 1 #include<iostream>
 2 using namespace std;
 3 #define ll long long
 4 ll count(ll x){//区间长度
 5     ll t=1;
 6     while(x>1){
 7         x=(x+1)/2;//不断合并向上
 8         t++;//高度++
 9     }
10     return t;
11 }
12 ll ans=0;
13 void query(ll l,ll r,ll root){
14     ans=max(ans,root);
15     if(l==r)return;
16     ll mid=l+(r-l)/2;
17     ll leftdepth=count(mid-l+1);
18     ll rightdepth=count(r-(mid+1)+1);
19     if(leftdepth>rightdepth){
20         query(l,mid,root*2);
21     }
22     else{
23         query(mid+1,r,root*2+1);
24     }
25 }
26 int main(void){
27     ll T;scanf("%lld",&T);
28     while(T--){
29         ans=0;
30         ll n;scanf("%lld",&n);
31         query(1,n,1);
32         printf("%lld\n",ans);
33     }
34     return 0;
35 }

 

posted @ 2022-05-06 16:19  Tiachi  阅读(53)  评论(0)    收藏  举报