考虑两种情况:
①结点m和n不在同一行
②结点m和n处在同一行
#include <iostream>
#include <cmath>
using namespace std;
int cal(int n){
int h = log(n) / log(2) + 1;
return h;
}
int main(){
int m, n;
while(cin >> m >> n){
if (m == 0 && n == 0)
break;
// n 节点和 m 节点的高度差
int h = cal(n) - cal(m);
int k = (int)pow(2, h);
//最后一层的起始节点为start = m * 2 ^ h
int start = m * k;
//以 m 节点为根结点的子树最右侧元素end = (1 + m) * 2 ^ h - 1
int end = (1 + m) * k - 1;
//以 m 节点为根结点的子树(除去最后一层)的元素总数tot = 2 ^ h - 1
int tot = k - 1;
//最后一层也是满的
if(end <= n){
tot += k;
}else{
if(n >= start){
tot += n - start + 1;
}
}
cout << tot << endl;
}
return 0;
}每一行的节点数等于right-left+1,把每一行相加起来即可。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m,left,right,cnt;
while((cin>>m>>n)&& n && m)
{
cnt=0;
left=right=m;
while(left<=n)
{
cnt=cnt+right-left+1;//每一层的节点数目为right-left+1。
left=2*left;
right=2*right+1;
if(right>n) right=n;
}
cout<<cnt<<endl;
}
return 0;
} 
京公网安备 11010502036488号