题意:给一个深为h的树(从0层开始),从root以"LRLRLRLR..."的指令顺序,问道最后一层第n个节点需要遍历的节点个数。
- Character 'L' means "go to the left child of the current node";
- Character 'R' means "go to the right child of the current node";
- If the destination node is already visited, Amr skips current command, otherwise he moves to the destination node;
- If Amr skipped two consecutive commands, he goes back to the parent of the current node before executing next command;
- If he reached a leaf node that is not the exit, he returns to the parent of the current node;
- If he reaches an exit, the game is finished.
题解:题意没怎么懂,走法叙述的好复杂,但下面有张图给了我想法;

看图可以发现几条性质:
1、任何node的 左子节点都是偶数,右子节点都是奇数;
2、若当前节点是 偶数则先走向右子节点,奇数则先走向左子节点;
3、考虑每个子树 记高h的最底层节点个数的一半为mid(有mid=1<<(h-1);):
若子树的root是奇数:①当n>mid,则会先走完root的左半边(即ans加上(1<<h)个节点),
且走到右半边子树root仍为奇数,
但在右子树中EXIT的相对位置减少mid;
(即图中E在以9为根的树中,在最下层的第(n-mid=6-4=)2位置);
②当n<=mid,就直接进入左半边,但子树root变为偶数,
加上根节点ans++ ,而EXIT相对位置不变;
若子树的root是偶数:①当n>mid,则EXIT在右子树中,且子树根节点变为奇数,
加上根节点ans++ ,EXIT相对位置n=n-mid ;
②当n<=mid,则先会走完root的右半边,即ans加上(1<<h)个节点;
root仍为偶数,
EXIT相对位置不变;
不语,一切尽在代码中:
#define INF 0x7fffffff
#define eps (1e-9)
#define maxn 1000000000
#define clearto(s,x) memset(s,x,sizeof(s))
using namespace std;
int m,h,tot=0;
long long n,mid;
int main()
{
//freopen("E:\DATA.txt","r",stdin);
//int TT=1,tt+=1; scanf("%d",&TT);
int i=0,j=0;
long long ans=0;
scanf("%d %I64d",&h,&n);
int root=1,odd=1,even=2;
while(h>0)
{ //不强制转换大数花挂 ::>_<::
mid=(long long)1<<(h-1);
if(root==odd)
{
if(n> mid)
{ ans+=(mid*2); h--; n=n-mid; }
else
{ root=even; ans+=1; h--; }
continue;
}
if(root==even)
{
if(n> mid)
{ root=odd; ans++; h--; n=n-mid; }
else
{ ans+=(mid*2); h--; }
}
}
printf("%I64d",ans);
return 0;
}