问题描述
给定一棵包含
n
n
n个结点的完全二叉树,结点按从根到叶、从左到右的顺序依次编号。你需要求出第
k
k
k个结点对应的子树拥有的结点数量。
例如,输入
3 // 询问次数
1 2 1 // n = 1, m = 2, k = 1
11 3 4 // n = 11, m = 3, k = 4
74 5 3
输出
1
2
24
解析
总结规律,序号为 k k k的结点的子节点最右端为 r c h i l d = k × m + 1 rchild = k \times m + 1 rchild=k×m+1,最左端的子节点序号为 l c h i l d = ( k − 1 ) × m + 2 lchild = (k - 1) \times m + 2 lchild=(k−1)×m+2,子节点的个数就是$ rchild - lchild$。要算出子树的结点总数,可以从k结点出发,将各层子节点数量相加,直到rchild > n,此时如果lchild > n则最后一层没有子节点,否则最后再加上lchild - n + 1。
#include <vector>
#include <iostream>
using namespace std;
int main()
{
long long lines, n, m, k;
cin >> lines;
while (lines--)
{
cin >> n >> m >> k;
long long l = (k - 1) * m + 2;
long long r = k * m + 1;
long long ans = 1;
while (r <= n)
{
ans += r - l + 1;
l = (l - 1) * m + 2;
r = r * m + 1;
}
ans += max(0LL, n - l + 1);
cout << ans << endl;
}
return 0;
}