zoukankan      html  css  js  c++  java
  • 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;
    }

  • 相关阅读:
    Codeforces Round #648 (Div. 2) A~F题解
    2020杭电多校第四场 Go Running 最小点覆盖等于二分图最大匹配数
    2019徐州网络赛 M Longest subsequence 序列自动机
    后缀数组模板题总结
    2020 Multi-University Training Contest 1 . Fibonacci Sum 水题改编
    悬线法
    欧拉回路,欧拉路径
    LGV算法 CodeForces 348D + 牛客多校 A Monotonic Matrix
    Kattis mapcolouring(状压dp)
    mysql解决错误:ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
  • 原文地址:https://www.cnblogs.com/lightspeedsmallson/p/5173966.html
Copyright © 2011-2022 走看看