思路:由于递归每一层都计数[l, r]中1和0的个数复杂度太高,极限情况下,递归过程中计数的复杂度:(1024^{11} = 2^{110}),这里用前缀和记录一下1的个数,就可以每一层(O(1))复杂度获得1的个数了,做法就是根据题目说的递归构造树,然后后续遍历
空间大小问题:题目中最长序列为(2^{10}),则二叉树最多11层,则总结点数为(2^{11} - 1)
#include<iostream>
#include<string>
using namespace std;
const int N = 2500, M = 1500;
struct node{
int l, r;
char val;
}tr[N];
int idx;
// 2^(l - 1) = 2^N => l = N + 1
int n;
int a[M];
char s[N];
void dfs(int l, int r, int u){
if(l == r){
if(s[l] == '0') tr[u].val = 'B';
else tr[u].val = 'I';
tr[u].l = tr[u].r = -1;
return;
}
tr[u].l = ++ idx, tr[u].r = ++ idx;
int ones = a[r] - a[l - 1];
if(ones == r - l + 1) tr[u].val = 'I';
else if(ones == 0) tr[u].val = 'B';
else tr[u].val = 'F';
int mid = l + r >> 1;
dfs(l, mid, tr[u].l), dfs(mid + 1, r, tr[u].r);
}
void trav(int u){
if(u == -1) return;
trav(tr[u].l), trav(tr[u].r);
cout << tr[u].val;
}
int main(){
cin >> n;
for(int i = 1; i <= 1 << n; i ++) cin >> s[i];
for(int i = 1; i <= 1 << n; i ++)
a[i] = a[i - 1] + (s[i] == '1');
dfs(1, 1 << n, 0);
trav(0);
return 0;
}