题意:一个满二叉树,给所有节点按从左到右的顺序从1开始编号。现每次给定一个节点编号,问以该节点为根的子树的最小编号和最大编号节点分别为多少号。(理解不了就看原题的图)
分析:使用lowbit,即二进制码中的最靠后的1和后面的0组成的数字。规律是这样的,对于以x为根的子树,以lowbit(x)为其高位和低位的分界线,该子树上的所有节点编号的高位(不包括lowbit(x)那一位)均与x相同。不在该子树上的点的编号的高位均与x不同。因此,只要算出以x的高位为高位的数字中最大和最小的两个即为所求。
View Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
usingnamespace std;
int main()
{
//freopen("t.txt", "r", stdin);
int t;
scanf("%d", &t);
while (t--)
{
int a;
scanf("%d", &a);
printf("%d %d\n", a - (a & (-a)) +1, a + (a & (-a)) -1);
}
return0;
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
usingnamespace std;
int main()
{
//freopen("t.txt", "r", stdin);
int t;
scanf("%d", &t);
while (t--)
{
int a;
scanf("%d", &a);
printf("%d %d\n", a - (a & (-a)) +1, a + (a & (-a)) -1);
}
return0;
}