【HDU5524 BC61 div1 B】【SET模拟】Subtrees 二叉树不同子节点树的子树个数
2015-11-01 10:14
471 查看
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 102 Accepted Submission(s): 58 Problem Description There is a complete binary tree with N nodes.The subtree of the node i has Ai nodes.How many distinct numbers are there of Ai? Input There are multiple test cases, no more than 1000 cases. For each case contains a single integer N on a line.(1≤N≤1018) Output The output of each case will be a single integer on a line:the number of subtrees that contain different nodes. Sample Input 5 6 7 8 Sample Output 3 4 3 5 Source BestCoder Round #61 (div.2) |
#include<stdio.h> #include<string.h> #include<ctype.h> #include<math.h> #include<iostream> #include<string> #include<set> #include<map> #include<vector> #include<queue> #include<bitset> #include<algorithm> #include<time.h> using namespace std; void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);} #define MS(x,y) memset(x,y,sizeof(x)) #define MC(x,y) memcpy(x,y,sizeof(x)) #define MP(x,y) make_pair(x,y) #define ls o<<1 #define rs o<<1|1 typedef long long LL; typedef unsigned long long UL; typedef unsigned int UI; template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;} template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;} const int N=0,M=0,Z=1e9+7,ms63=1061109567; int casenum,casei; LL b[70],s[70]; set<LL>sot; LL n; int DEP; int ans; void init() { for(int i=0;i<=60;i++) { b[i]=1ll<<i; s[i]=b[i]*2-1; } } void go(int dep,LL x,LL son) { sot.insert(son); if(dep==0)return; LL o=x-s[dep-1];//求出这个点是这层的第几个点 if(o!=1)//左面有 { sot.insert(s[DEP-dep]);//有到叶子距离为DEP-dep的完全二叉树 } if(o!=b[dep])//右面有 { if(DEP-1-dep>=0)sot.insert(s[DEP-1-dep]);//有到叶子距离为DEP-1-dep的完全二叉树 } if(x&1)//如果在右面 { LL lson=s[DEP-dep];//左面有这么大一棵树 son+=lson+1; } else//如果在左面 { LL rson=s[DEP-dep]>>1;//右面有这么大一棵树 son+=rson+1; } go(dep-1,x>>1,son); } int main() { init(); while(~scanf("%lld",&n)) { sot.clear(); for(DEP=0;s[DEP]<n;DEP++);//找到它所在的层次 go(DEP,n,1); printf("%d\n",sot.size()); } return 0; } /* 【题意】 给你一个恰好有n([1,1e18])节点的完全二叉树,问你这个二叉树有多少个子树节点数不同的节点。 其中,完全二叉树的定义是:除了最后一层,其他层的节点都是满的。且最后一层的节点都是分布在最左侧。 【类型】 SET模拟 【分析】 模拟式的解题思维往往都是很有价值的。 我们首先可以预处理出——深度恰好为dep的满二叉树的该层节点数以及总共节点数 然后从关键点,也就是最后一个点开始,向上沿着链走,一直走到根节点。 我们可以更新出,走到这个链上某个节点时的子节点数。 现在有一个很好玩而且很有意义的性质, 就是这个节点同层的左边的都是满二叉树,同层的右边的是少一深度的满二叉树。 于是我们就把这3种子节点数插入set中。 最后的set.size()就是答案 【时间复杂度&&优化】 O(log(n)) 【数据】 input 1000000000000000000 output 118 */
相关文章推荐
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例
- PHP实现克鲁斯卡尔算法实例解析
- C#获取关键字附近文字算法实例