P8168 [eJOI 2021] BinSearch

题目描述

```cpp bool binary_search(int n, int p[], int target){ int left = 1, right = n; while(left < right){ int mid = (left + right) / 2; if(p[mid] == target) return true; else if(p[mid] < target) left = mid + 1; else right = mid - 1; } if(p[left] == target) return true; else return false; } ``` 众所周知,当上述函数在传入一个单调不递减的数组 $\texttt p$ 且 $\texttt{target}$ 在数组 $\texttt p$ 中出现过,那么会返回 $\texttt{true}$。然而,当 $\texttt p$ 不存在单调性时则不然。 给定正整数 $n$ 和一个数组 $b_1,\dots,b_n \in \{\texttt{true},\texttt{false}\}$。数据保证存在一个正整数 $k$,使得 $n=2^k-1$。 规定 $S(p)$ 为 $i \in \{1,\dots,n\}$ 时 $\texttt{binary\_search(n, p, i)}$ 返回值不为 $b_i$ 的个数。你的任务是求一个 $\{1,\dots,n\}$ 的排列 $p$,使得 $S(p)$ 尽可能小(具体请见评分规则)。

输入格式

**本题有多组数据。** 第一行一个正整数 $T$,表示数据组数。 每组数据的第一行包含一个正整数 $n$。第二行包含一个长度为 $n$ 的字符串(只含有字符 `0` 和 `1` 且无空格)。其中当第 $i$ 个字符为 `1` 时,则 $b_i=\texttt{true}$,否则 $b_i=\texttt{false}$。

输出格式

输出 $T$ 行,每行输出求得的排列 $p$。**Special Judge 对输出格式要求非常严格,每行行末不能有空格等多余字符。**

说明/提示

#### 评分规则 - 当一个子任务中的所有排列 $p$ 均满足 $S(p) \le 1$ 时,得分为该子任务总分的 $100\%$。 - 否则当一个子任务中的所有排列 $p$ 均满足 $0 \le S(p) \le \lceil \log_2 n \rceil$ 时,得分为该子任务总分的 $50\%$。 由于洛谷评分机制,每个测试点的实际得分为上式下取整的结果。例如,当该子任务的总分为 $3$ 且该子任务中的所有排列 $p$ 均满足 $0 \le S(p) \le \lceil \log_2 n \rceil$ 时,得分为 $1$ 而不是 $1.5$。 #### 样例 1 解释 前两组数据满足 $S(p)=0$。 第三组数据中 $S(p)=1$,因为 $\texttt{binary\_search(n, p, 2)}=\texttt{true} \neq b_2$。 第四组数据中 $S(p)=1$,因为 $\texttt{binary\_search(n, p, 4)}=\texttt{true} \neq b_4$。 #### 样例 2 解释 两组数据均满足 $S(p)=0$。 #### 数据规模与约定 **本题采用捆绑测试。** - Subtask 1(3 pts):$b_i=\texttt{true}$。 - Subtask 2(4 pts):$b_i=\texttt{false}$。 - Subtask 3(16 pts):$1 \le n \le 7$。 - Subtask 4(25 pts):$1 \le n \le 15$。 - Subtask 5(22 pts):$n=2^{16}-1$ 且 $b_i$ 数据随机。 - Subtask 6(30 pts):无特殊限制。 对于 $100\%$ 的数据,$1 \le T \le 7000$,$1 \le \sum n \le 10^5$,$\forall n \in \{n|n=2^k-1,k \in \N^*\}$。 #### 说明 本题译自 [eJOI2021](https://sepi.ro/ejoi/2021) Day 2 A BinSearch。欢迎通过私信或发帖的方式对自行编写的 [Special Judge](https://www.luogu.com.cn/paste/5fdi0fvc) 进行 hack。