描述
输入描述:
输入数据包括多行,每行给出一组测试数据,包括两个整数 m,n。
最后一行 0 0
表示输入结束。
输出描述:
对于每一组测试数据,输出一行,该行包含一个整数,给出结点 m 所在子树中包括的结点的数目。
输入
3 12
0 0
输出
4
代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
using namespace std;
int main() {
int m, n;
while (1) {
scanf("%d%d", &m, &n);
if (m == 0 && n == 0) {
break;
}
int i = 1; // 获取层数 从1开始
int begin_level; // 存储子树的根在第几层
int final_level; // 大树总共有几层
// 2^(i-1) ~ 2^i-1
// 1 << i ==> 2^i
while (1) {
if (m >= 1 << (i - 1) && m < 1 << i) {
begin_level = i;
}
if (n >= 1 << (i - 1) && n < 1 << i) {
final_level = i;
break;
}
++i;
}
int left_side = m;
int right_side = m;
for (i = begin_level; i < final_level; ++i) {
left_side = 2 * left_side;
right_side = 2 * right_side + 1;
}
int treeNum;
// left_side > n 说明 实际的最左最右孩子在倒数第2层
// 子树 是一颗 从 begin_level ~ final_level-1 满二叉树
if (left_side > n) {
treeNum = (1 << (final_level - begin_level)) - 1;
}
else if (n <= right_side) {
treeNum = (1 << (final_level - begin_level)) - 1;
treeNum += n - left_side + 1;
}
else {
treeNum = (1 << (final_level - begin_level + 1)) - 1;
}
printf("%d\n", treeNum);
}
return 0;
}