您的位置:首页 > 其它

URAL 1117

2013-08-23 15:26 120 查看
题目大意:一颗深度不超过31的满二叉树,按照中根遍历编号,求从a,a+1,a+2,...依次走到b时跳过的层的总数(a为m,n中的较小的数,b为较大的数)。

例如:

input:           output:

1 5              2(1->2,2->3,3->4(跳过一层),4->5(跳过一层))

Time Limit:1000MS     Memory
Limit:65536KB     64bit IO Format:%I64d
& %I64u


数据规模:1<=m,n<=2^31-1。
理论基础:满二叉树中根遍历时的编号规律,请自行百度。
题目分析:满二叉树中根遍历编号时,每个编号表示成二进制数时,不为0的最低位的位置(lowbit)为此节点所在的高度。例如:2,6的高度为2;4的高度为3;8的高度为4;1,3,5,7,...的高度为1。这个在求解处理时会用到。
这样的话我们可以得出:dp[i]=(dp[i-1]+i-2)<<1,dp[i]表示根节点为i的子树从左下角到右下角跳过的层的总数。
将所求分成两棵子树,求解即可。
代码如下:

#include<iostream>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<ctime>
#include<vector>
using namespace std;
typedef double db;
#define DBG 0
#define maa (1<<31)
#define mii ((1<<31)-1)
#define ast(b) if(DBG && !(b)) { printf("%d!!|\n", __LINE__); while(1) getchar(); }  //调试
#define dout DBG && cout << __LINE__ << ">>| "
#define pr(x) #x"=" << (x) << " | "
#define mk(x) DBG && cout << __LINE__ << "**| "#x << endl
#define pra(arr, a, b)  if(DBG) {\
dout<<#arr"[] |" <<endl; \
for(int i=a,i_b=b;i<=i_b;i++) cout<<"["<<i<<"]="<<arr[i]<<" |"<<((i-(a)+1)%8?" ":"\n"); \
if((b-a+1)%8) puts("");\
}
template<class T> inline bool updateMin(T& a, T b) { return a>b? a=b, true: false; }
template<class T> inline bool updateMax(T& a, T b) { return a<b? a=b, true: false; }
typedef long long LL;
typedef long unsigned int LU;
typedef long long unsigned int LLU;
#define N 35
int a,b,dp
;
int solve(int high)
{
if(high==1)return 0;
int r,nr=1;
r=1<<30;
while(!(r&high))r=r>>1;
while(!(r&(1<<nr)))nr++;
if(r==high)return dp[nr]+nr-1;
return dp[nr]+((nr-1)<<1)+solve(high^r);
}
int main()
{
while(~scanf("%d%d",&a,&b))
{
int r,nr=1;
memset(dp,0,sizeof dp);
if(a>b)a=a+b,b=a-b,a=a-b;
r=1<<30;
while(!(r&b))r>>=1;
while(!(r&(1<<nr)))nr++;
nr++;
for(int i=2;i<=nr;i++)
{
dp[i]=(dp[i-1]+i-2)<<1;
}
dout<<nr<<endl;
pra(dp,1,nr)
printf("%d\n",solve(b)-solve(a));
}
return 0;
}

           其中,r代表右子树,l表示左子树,根据编号规律,找到比较大数小的最大的2^k的数,即可将原问题拆分成子树问题。

by:Jsun_moon http://blog.csdn.net/Jsun_moon
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  URAL 1117 Hierarchy