HDU 5524 Subtrees [想法题/LCA]
2015-11-01 20:38
393 查看
题意:给出N个节点的完全二叉树,问此树中所有的Subtree的Size有几种。
范围:N<=10的18次
解法:可以知道,满二叉树的子树的Size只有1,3,7,15,31,63……,共有树高H个,那么多的一些种类只能是非满二叉树贡献出来的,什么时候一棵树会是非满二叉树呢,那么必然N不是1.3.7.15....然后树中某个节点向上都是不满的,最低的这个节点就是N号点与N+1号点的LCA,然后只要观察一些其他满二叉的子树的最大树高h是几就可以了,发现如果N是最底下一层的左半部分,那么h是H-2,否则是H-1,H是整个树高,细节部分看代码吧,很短的。
范围:N<=10的18次
解法:可以知道,满二叉树的子树的Size只有1,3,7,15,31,63……,共有树高H个,那么多的一些种类只能是非满二叉树贡献出来的,什么时候一棵树会是非满二叉树呢,那么必然N不是1.3.7.15....然后树中某个节点向上都是不满的,最低的这个节点就是N号点与N+1号点的LCA,然后只要观察一些其他满二叉的子树的最大树高h是几就可以了,发现如果N是最底下一层的左半部分,那么h是H-2,否则是H-1,H是整个树高,细节部分看代码吧,很短的。
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<iostream> #include<stdlib.h> #include<set> #include<map> #include<queue> #include<vector> #include<bitset> #pragma comment(linker, "/STACK:1024000000,1024000000") template <class T> bool scanff(T &ret){ //Faster Input char c; int sgn; T bit=0.1; if(c=getchar(),c==EOF) return 0; while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar(); sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0'); while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0'); if(c==' '||c=='\n'){ ret*=sgn; return 1; } while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10; ret*=sgn; return 1; } #define inf 1073741823 #define llinf 4611686018427387903LL #define PI acos(-1.0) #define lth (th<<1) #define rth (th<<1|1) #define rep(i,a,b) for(int i=int(a);i<=int(b);i++) #define drep(i,a,b) for(int i=int(a);i>=int(b);i--) #define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next) #define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++) #define mem(x,val) memset(x,val,sizeof(x)) #define mkp(a,b) make_pair(a,b) #define findx(x) lower_bound(b+1,b+1+bn,x)-b #define pb(x) push_back(x) using namespace std; typedef long long ll; typedef pair<int,int> pii; int main(){ ll n; while(scanf("%lld",&n)!=EOF){ if(n==1){ printf("1\n"); continue; } int h=1; ll x=2; while(x-1<n){ x<<=1; h++; } if(x-1==n){ printf("%d\n",h); continue; } int th=h; ll xx=n,yy=n+1; while(xx!=yy){ xx>>=1; yy>>=1; th--; } if(n<((1LL<<(h-1))-1)+(1LL<<(h-2)))printf("%d\n",th+h-2); else printf("%d\n",th+h-1); } return 0; }
相关文章推荐
- linux yum怎么安装 及过程
- Mangos源码分析(1):服务器结构探讨之最简单的结构
- mysql事务的提交和回滚
- Activity的启动模式与startActivityForResult的关系
- HDOJ 题目 1300 Pearls(DP水)
- diy toy: image auto-handler
- Java抽象类与接口的区别
- 《CLR via C#》---枚举标志和标志位
- 【cocos2d-x3.2游戏开发】 lua 类, 继承, 面向对象
- 【2015/11/1】C学习日志_Day11&12 数据类型 指针 内存对齐 函数指针
- LeJOS学习(8):Sensor的API研究-InfraRedSensor
- 用数组取指定模式地址的内容
- 程序47 读取7个数(1—50)的整数值,每读取一个值,程序打印出该值个数的*。
- android 读取联系人实例
- 接口层输入
- week9---11月4日 JS基础(二)
- Meteor错误:TypeError: Meteor.userId is not a function
- ACM学习历程—HDU1041 Computer Transformation(递推 && 大数)
- MFC程序内存泄露检查
- Mysql创建触发器实现不同表的插入、更新、删除操作