(507C)codeforce

来源:互联网 发布:网络新闻稿 编辑:程序博客网 时间:2024/05/19 00:14
#include<iostream>
#include<cstdio>
#include<string.h>
#include<string>
#include<set>
#include<algorithm>
#include<cmath>

#define ll __int64
#define MAX 1000009
using namespace std;

/*
题目大意:给出树的深度h,注意树是从0层开始算的,和最下面一层的第n个节点。问以LRLRLRLR。。。。的顺序走到那个节点的访问多少节点。
(PS:读成了整棵树的第n个节点,直接测试样例就过不去啊。。。。)
1、L走到节点的左子树。
2、R走到节点的右子树。
3、如果要到节点已经被访问过,跳过该步。
4、如果连续跳过两步,返回该节点的父节点。
5、如果到了非出口的叶子节点,返回该节点的父节点。
计算出从根到那个节点的路径。(LR的序列)
从L开始第一步,如果走的方向和路径相同,那么节点数+1,否则,就会走完那个子树的所有节点,然后向反方向走。
 */


ll sum(int x)
{
    ll ans = 1;
    for(int i = 0; i<x; i++)
        ans*=2;
    return ans;
}


int main()
{
    ll h,n;
    int f;
    ll ans;
    while(cin>>h>>n)
    {
        ll l = 1;
        ll r = sum(h);//最后一层的节点个数,实际你可以看做不断对底层二分,找相应区间
        f = 1;
        ans = 0;
        for(int i = 0; i<h; i++)
        {
            ll mid = (l+r)>>1;//每层二分
            ll other = sum(h - i) - 1;//子树节点个数
            //cout<<"other="<<other<<endl;
            if(f)
            {
                if(n>mid)
                {
                    l = mid + 1;
                    ans+=other;//加儿子节点个数
                    ans++;
                    f = 1;
                }
                else
                {
                    r = mid;
                    ans++;
                    f = 0;
                }
            }
            else
            {
                if(n<=mid)
                {
                    r = mid;
                    ans+=other;//加儿子节点个数
                    ans++;
                    f = 0;
                }
                else
                {
                    l = mid + 1;
                    ans++;
                    f = 1;
                }
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
}
0 0
原创粉丝点击