考虑两种情况:
①结点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;
}