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