分析可以发现所有子树的种数不会太大可以直接暴力统计。
递归处理当前的树,首先记录当前树的大小,然后对于它的两颗子树,找到其中那颗满二叉树暴力统计子树种数,然后递归处理另一颗子树。注意统计判重。
找满二叉树的过程可以通过枚举树的高度,然后判断另一颗树的高度与它相差是否在1之内。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
set<LL> s;
bool judge(int j,LL n)
{
return (1LL<<j-1)-1<=n&&n<(1LL<<j)-1;
}
void dfs(LL n)
{
if(n<=0)
return ;
s.insert(n);
--n;
int i=1;
while((1LL<<i)-1<=n)
{
LL x=(1LL<<i)-1;
LL y=n-x;
if(x!=0)
s.insert(x);
if(judge(i+1,y)||judge(i,y))
break;
++i;
}
dfs(n-((1LL<<i)-1));
}
int main()
{
LL n;
while(cin>>n)
{
s.clear();
dfs(n);
cout<<s.size()<<endl;
}
return 0;
}