题意:一棵树,按要求的顺序遍历,问在序号n之前要遍历多少个结点。
思路:二分。当结点在左子树中且此时遍历顺序为L时,ans不变并将遍历顺序变为R,当遍历顺序为R时,ans加上右子树所有的结点数,注意此时的遍历顺序仍应该是R。当结点在右子树时情况类似。/*I have given up the treatment-_-||*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<climits>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
using namespace std;
#define mod 1000000
typedef long long LL;
const int maxn=60010;
const int maxm=500;
const int INF=2*1e9;
int n,m;
int main()
{
int i,j;
int h;
LL t;
LL a=1;
scanf("%d%I64d",&h,&t);
for(i=1;i<=h;i++){
a*=2;
}
LL ans=h;
LL left=1;
LL right=a;
int flag=0;
while(1){
LL mid=(left+right)/2;
//printf("*%I64d\n",ans);
if(left==right){
break;
}
if(t>mid&&flag==0){
left=mid+1;
ans+=a-1;
a/=2;
}
else if(t>mid&&flag==1){
left=mid+1;
a/=2;
flag=0;
}
else if(t<=mid&&flag==0){
right=mid;
a/=2;
flag=1;
}
else if(t<=mid&&flag==1){
right=mid;
ans+=a-1;
a/=2;
}
}
printf("%I64d\n",ans);
}
/*I have given up the treatment-_-||*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<climits>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
using namespace std;
#define mod 1000000
typedef long long LL;
const int maxn=60010;
const int maxm=500;
const int INF=2*1e9;
int n,m;
int main()
{
int i,j;
int h;
LL t;
LL a=1;
scanf("%d%I64d",&h,&t);
for(i=1;i<=h;i++){
a*=2;
}
LL ans=h;
LL left=1;
LL right=a;
int flag=0;
while(1){
LL mid=(left+right)/2;
//printf("*%I64d\n",ans);
if(left==right){
break;
}
if(t>mid&&flag==0){
left=mid+1;
ans+=a-1;
a/=2;
}
else if(t>mid&&flag==1){
left=mid+1;
a/=2;
flag=0;
}
else if(t<=mid&&flag==0){
right=mid;
a/=2;
flag=1;
}
else if(t<=mid&&flag==1){
right=mid;
ans+=a-1;
a/=2;
}
}
printf("%I64d\n",ans);
}