poj2309

题意:一个满二叉树,给所有节点按从左到右的顺序从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;
}
posted @ 2011-05-23 19:37  undefined2024  阅读(460)  评论(0)    收藏  举报