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 }

浙公网安备 33010602011771号