题解:模拟就可以了。
记录一下当前模拟到哪个点了以及下一步该往左还是往右。每次判断一下目标在哪一棵子树内,如果在要去的子树里面,那就直接走,把下一步反过来;如果不在,就说明要先把要去的子树整棵走一遍,那就把答案加上那棵子树的大小,然后走到另一棵去,下一次的方向还是和这次一样。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int h;
long long n,x,ans;
bool LR;
int main()
{
scanf("%d%I64d",&h,&n);
LR=0;x=(1ll<<(h-1));
for(long long i=h-1;i>=0;i--)
{
ans++;
if(!LR)
{
if(n>x){ans+=((1ll<<(i+1))-1);if(i) x+=(1ll<<(i-1));LR^=1;}
else{if(i) x-=(1ll<<(i-1));}
}
else
{
if(n<=x){ans+=((1ll<<(i+1))-1);if(i) x-=(1ll<<(i-1));LR^=1;}
else{if(i) x+=(1ll<<(i-1));}
}
LR^=1;
}
printf("%I64d\n",ans);
return 0;
}