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的子树从左下角到右下角跳过的层的总数。
将所求分成两棵子树,求解即可。
代码如下:
其中,r代表右子树,l表示左子树,根据编号规律,找到比较大数小的最大的2^k的数,即可将原问题拆分成子树问题。
by:Jsun_moon http://blog.csdn.net/Jsun_moon
例如:
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
- URAL 1117 - Hierarchy(递推或递归)
- 【满二叉树 && dp】URAL - 1117 Hierarchy
- URAL - 1117 Hierarchy(找规律)
- Ural 1117 Hierarchy
- URAL 1117. Hierarchy(DP)
- URAL1534 进球
- 51Nod 1117 聪明的木匠(贪心+优先队列)
- ural 2070. Interesting Numbers
- URAL 1146 Maximum Sum(最大子矩阵的和 DP)
- URAL 1785 Lost in Localization
- URAL 1993 This cheeseburger you don't need 模拟题
- Ural 1025-Democrary in Danger
- Binary Apple Tree_ural1018_树状dp
- ural 1018 Binary Apple Tree(树形DP)
- URAL 1627 Join(生成树计数)
- URAL 1014
- URAL 2035 Another Dress Rehearsal 水题、易错
- Ural 1303. Minimal Coverage
- Ural 2037. Richness of binary words (打表+构造)