poj2309

题意:一个满二叉树,给所有节点按从左到右的顺序从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 ;
}

你可能感兴趣的:(poj)