hdu5524Subtrees+递归模拟

来源:互联网 发布:淘宝店铺产品布局 编辑:程序博客网 时间:2024/06/05 01:54

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)

问一个N个节点的满二叉树,有多少种不同的节点,该节点的子节点数不同。。
对于一个节点如果它的子树是满二叉树,那么不同的节点数就是满二叉树的层数。如果不是满二叉树,那么这个节点肯定是特别的,
所以类似于那种线段的方法进行编号,逐层递归,如果是满二叉树返回层数,如果不是右左右进行递归。如果继续往下递归,出现了满二叉树,只需要摘一个最大的满二叉树就好了。最后。与根节点合并,
最开始写了一个纯暴力递归。。其实吧。。既然是完全二叉树。满二叉树还是挺多了。 跑的很快。1e18直接秒了。。

#include<bits/stdc++.h>using namespace std;#define LL long longLL fulltree,badtree;LL n;void Find(LL x){    LL l=x,r=x;    LL deepl=0,deepr=0;;    while(2*l<=n){        l=l*2;        deepl++;    }    while(2*r+1<=n){        r=2*r+1;        deepr++;    }    if(deepl==deepr) fulltree=max(fulltree,deepl);    else{        badtree++;        Find(2*x);        Find(2*x+1);    }}int main(){    while(cin>>n){        fulltree=0;        badtree=0;        Find(1);        cout<<fulltree+badtree+1<<endl;    }    return 0;}/*暴力,相当于要遍历每个点啊,1e18啊。。LL ans;LL n;set<LL>Q;set<LL>::iterator it;LL Find(LL x){    if(x>n) return 0;    LL temp=Find(x*2)+Find(x*2+1);    Q.insert(temp);    return temp+1;}int main(){    while(cin>>n){        ans=0;        Q.clear();        Find(1);        //for(it=Q.begin();it!=Q.end();it++) cout<<*it<<endl;        cout<<Q.size()<<endl;    }    return 0;}*/
0 0
原创粉丝点击