46| FBI树

一、核心思路

用前缀和快速判断区间类型,递归不断二分,先分左右,最后输出自己,就是 FBI 树。

1.前缀和预处理(快速查区间)

  • f[i] 存:前 i 个字符里 1 的个数
  • 想知道 [l, r] 是什么类型:
    • 和为 0 → B
    • 和 = 长度 → I
    • 其他 → F

2. 递归分治(核心)

把当前字符串 分成左右两半

  • 左:l ~ mid
  • 右:mid+1 ~ r

一直分,分到不能再分(只剩一个字符) 为止。

3. 叶子节点直接输出

分到最小单位

  • 输出 B/I
  • 立刻返回,不再继续分割
  • 防止无限递归、越界

二、代码实现

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 11;
int f[1 << N];
int n;
void dfs(int l, int r) 
{
	if(l > r) return; 
	char ret;  // 判断字串类型 
	if (f[r] - f[l-1] == (r - l + 1)) ret = 'I';
	else if (f[r] - f[l-1] == 0) ret = 'B';
	else ret = 'F';
	// 递归构建 
	if(l == r)  // 叶子节点直接输出 
	{
		cout << ret;
		return; 
	 } 
	int mid = (l + r) >> 1;
	dfs(l, mid); // 左子树 
	dfs(mid + 1, r); // 右子树 
	cout << ret; // 根节点 
}
signed main()
{
	cin >> n;
	n = (1 << n);
	for (int i = 1; i <= n; i++)
	{
		int t = 0;
		char ch; cin >> ch;
		if(ch == '1') t = 1;
		f[i] = f[i-1] + t;
	}
	dfs(1,n);
	
	return 0;
 } 
相关推荐
2401_8920709821 小时前
【Linux C++ 日志系统实战】LogFile 日志文件管理核心:滚动策略、线程安全与方法全解析
linux·c++·日志系统·日志滚动
世人万千丶21 小时前
Flutter 框架跨平台鸿蒙开发 - 恐惧清单应用
学习·flutter·华为·开源·harmonyos·鸿蒙
yuzhuanhei21 小时前
Visual Studio 配置C++opencv
c++·学习·visual studio
小O的算法实验室21 小时前
2026年ASOC,基于深度强化学习的无人机三维复杂环境分层自适应导航规划方法,深度解析+性能实测
算法·无人机·论文复现·智能算法·智能算法改进
‎ദ്ദിᵔ.˛.ᵔ₎1 天前
LIST 的相关知识
数据结构·list
一轮弯弯的明月1 天前
贝尔数求集合划分方案总数
java·笔记·蓝桥杯·学习心得
不爱吃炸鸡柳1 天前
C++ STL list 超详细解析:从接口使用到模拟实现
开发语言·c++·list
M--Y1 天前
Redis常用数据类型
数据结构·数据库·redis
十五年专注C++开发1 天前
RTTR: 一款MIT 协议开源的 C++ 运行时反射库
开发语言·c++·反射
‎ദ്ദിᵔ.˛.ᵔ₎1 天前
STL 栈 队列
开发语言·c++