Codeforces Round #287 (Div. 2) C

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章