• HDU 5524:Subtrees


    Subtrees

     
     Accepts: 60
     
     Submissions: 170
     Time Limit: 2000/1000 MS (Java/Others)
     
     Memory Limit: 131072/131072 K (Java/Others)
    问题描述
    一棵有N个节点的完全二叉树,问有多少种子树所包含的节点数量不同。
    输入描述
    输入有多组数据,不超过1000组.
    每组数据输入一行包含一个整数N.(1leq Nleq {10}^{18})(1N1018)
    输出描述
    对于每组数据输出一行,表示不同节点数的子树有多少种.
    输入样例
    5
    6
    7
    8
    输出样例
    3
    4
    3
    5

    一颗完全二叉树,左右子树都会为完全二叉树,其中必然有一个最后一层是满的。对于最后一层是满的完全二叉树,每一层的节点的子树形态都是相同的,只统计logN种,然后递归处理另一颗子树。最后对记录下的所有子树根据节点数判重.

    这道题想了很久,果然递归真的是省事啊。。。

    网上的题解完全看不懂什么意思,之前也一直不敢写递归,总怕出错。这次敲完爽翻了。我真是太弱了。。。这道题兴奋半天。。。

    具体解释见代码:

    #pragma warning(disable:4996)  
    #include <iostream>  
    #include <algorithm>  
    #include <cmath>  
    #include <vector>  
    #include <string>  
    #include <cstring>
    #include <set>
    using namespace std;
    
    typedef long long ll;
    
    ll n;
    set<ll>an;
    
    void solve(ll x)
    {
    	if (x <= 0)
    		return;
    	if (x == 1)
    	{
    		an.insert(0);
    		return;
    	}
    	int i;
    	ll num, k, nn, nk;
    	for (i = 0; i <= 60; i++)
    	{
    		num = (1LL << i);
    		if ((num - 1) == x)//中奖了,是满二叉树(其实早晚会中奖......)
    		{
    			k = 0;
    			nn = 2;
    			while (k + 1 <= x)
    			{
    				an.insert(k);
    				k = k + nn;
    				nn = nn << 1;
    			}
    			return;
    		}
    		if (num >= x)
    		{
    			break;
    		}
    	}
    	an.insert(x - 1);
    	i--;
    	nn = (1LL << i) - 1;//除去最后一层的节点数
    	k = x - nn;//最后一层的节点数
    
    	nk = ((1LL << i) >> 1);//最后一层应该有的一半节点数
    	ll temp = (nn - 1) >> 1;
    	ll le, ri;
    	if (k <= nk)
    	{
    		le = temp + k;//搜索左子树节点
    		ri = temp;//搜索右子树节点
    	}
    	else
    	{
    		le = temp + nk;
    		ri = temp + k - nk;
    	}
    	solve(le);
    	solve(ri);
    }
    
    int main()
    {
    	//freopen("i.txt", "r", stdin);
    	//freopen("o.txt", "w", stdout);
    
    	while (cin >> n)
    	{
    		an.clear();
    		solve(n);
    		cout << an.size() << endl;
    	}
    	//system("pause");
    	return 0;
    }

  • 相关阅读:
    【转】 robotframework(rf)中对时间操作的datetime库常用关键字
    在RobotFramework--RIDE中把日期转化为整型进行运算
    Oracle中date转为timstam可以函数to_timestamp的方式来转化
    Java项目缺少.project文件
    数据库时间戳转换日期(MYSQL数据库)
    spring+struts+mybatis中关于报错org.hibernate.exception.GenericJDBCException: Connection is read-only. Queries leading to data modification are not allowed 的产生原因及解决方案
    新加字段问题(增加联合主键)
    集合问题
    数组面试题
    集合的问题
  • 原文地址:https://www.cnblogs.com/lightspeedsmallson/p/5173966.html
Copyright © 2020-2023  润新知