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;
}