2015/1/24
其实题目水。。但是我沙比:sacnf("%d%d",&n,&m);了。。还一直在找后面代码的错
不要想着去建树,不可能的。
去找规律。。
从目标节点往根节点回走!
lson = fa<<!; rson = fa*2+1. 那么转变下就是 fa = son/2;
然后判断下,fa和son的奇偶性是否相同,相同就表示,他走到fa节点的时候遍历了不包含目标节点的另一颗子树(而且是完全遍历) 。
这样问题就简单了。
只要计算他走下来的时候多走了那几颗子树(计算出节点数量)再和路径节点数加起来就是答案了。
=...=我真是个沙比,不说了,吃药去了。
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<climits>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
#define mod 10007
#define lson pos<<1,l,mid
#define sc(n) scanf("%d",&n)
#define rson pos<<1|1,mid+1,r
#define pr(n) printf("%d\n",n)
#define met(n,m) memset(n, m, sizeof(n))
#define F(x,y,i) for(int i = x;i > y; i--)
#define f(x,y,i) for(int i = x;i < y; i++)
#define ff(x,y,i) for(int i = x;i <= y; i++)
#define FF(x,y,i) for(int i = x;i >= y; i--)
const int N=100500;
const int inf = INT_MAX;
int Max(int a,int b)
{
return a>b?a:b;
}
int Min(int a,int b)
{
return a<b?a:b;
}
int main()
{
__int64 n, m, tot, x;
while(~scanf("%I64d%I64d",&n,&m))
{
__int64 num = m;
__int64 sm = (__int64)pow(2.0,n);
__int64 sum = 0;
int cnt = 0;
int temp ;
if(num > sm/2 )
{
sum = (__int64 )(pow(2.0,n)-1);
}
num = (__int64)pow(2.0,n) + m - 1;
if(num % 2) temp = 1;
else temp = 0;
while(num > 1)
{
num/=2;
cnt++;
if(num<=1)break;
if(num%2 == temp)
{
sum+= (__int64)pow(2.0,cnt) - 1;
}
temp = num%2;
}
sum+=cnt;
printf("%I64d\n",sum);
}
return 0;
}