题意:一个满二叉树,给所有节点按从左到右的顺序从1开始编号。现每次给定一个节点编号,问以该节点为根的子树的最小编号和最大编号节点分别为多少号。(理解不了就看原题的图)
分析:使用lowbit,即二进制码中的最靠后的1和后面的0组成的数字。规律是这样的,对于以x为根的子树,以lowbit(x)为其高位和低位的分界线,该子树上的所有节点编号的高位(不包括lowbit(x)那一位)均与x相同。不在该子树上的点的编号的高位均与x不同。因此,只要算出以x的高位为高位的数字中最大和最小的两个即为所求。
View Code
#include
<
iostream
>
#include < cstdio >
#include < cstdlib >
#include < cstring >
using namespace 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 );
}
return 0 ;
}
#include < cstdio >
#include < cstdlib >
#include < cstring >
using namespace 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 );
}
return 0 ;
}