「KDOI-10」反回文串

题目背景

[English Statement](https://www.luogu.com.cn/problem/T519008). You must submit your code at the Chinese version of the statement. **本场比赛所有题目从标准输入读入数据,输出到标准输出。**

题目描述

我们称一个长度为 $m$ 的字符串 $r$ 是回文的,当且仅当 $r_i=r_{m+1-i}$ 对所有 $1\le i\le m$ 均成立。 给定一个长度为 $n$ 的字符串 $s$,你需要把 $s$ 分成若干个非空子序列,使得每一个子序列都**不是**回文的,并最大化划分成的子序列数。 形式化地说,你需要给出一组序列 $(a_1,a_2,\ldots,a_k)$,满足: - 对于任意 $1\le i\le k$,记 $l_i$ 为 $a_i$ 的长度,则 $l_i\ge 1$,且 $1\le a_{i,1}<a_{i,2}<\cdots<a_{i,l_i}\le n$; - 对于任意 $1\le i\le n$,恰好存在一个二元组 $(p,q)$,使得 $a_{p,q}=i$; - 对于任意 $1\le i\le k$,记字符串 $t=s_{a_{i,1}}s_{a_{i,2}}\ldots s_{a_{i,l_i}}$,则 $t$ 不是回文的。 在此基础上,你需要最大化 $k$ 的值;或者判断不存在一种合法的方案。 特别地,如果 $k$ 的值不是最大的,你也可能获得一定的部分分。

输入输出格式

输入格式


从标准输入读入数据。 **本题有多组测试数据。** 输入的第一行包含一个正整数 $c$,表示测试点编号。$c=0$ 表示该测试点为样例。 第二行包含一个正整数 $q$,表示测试数据组数。 对于每组测试数据: - 第一行包含一个正整数 $n$,表示字符串 $s$ 的长度; - 第二行包含一个长度为 $n$ 的字符串 $s$。保证 $s$ 中仅包含小写英文字母。

输出格式


输出到标准输出。 对于每组测试数据: - 如果不存在一种合法的方案,输出一行一个字符串 `Shuiniao`; - 否则,你需要: - 在第一行输出一个字符串 `Huoyu`; - 第二行输出一个正整数 $k$ $(1\le k\le n)$,表示你划分成的子序列个数; - 接下来 $k$ 行,对于第 $i$ 行 $(1\le i\le k)$: - 首先输出一个正整数 $l_i$ $(1\le l_i\le n)$,表示第 $i$ 个子序列的长度; - 接下来输出 $l_i$ 个正整数 $a_{i,1},a_{i,2},\ldots, a_{i,l_i}$ $(1\le a_{i,j}\le n)$,表示第 $i$ 个子序列。 请注意,你的输出需要满足题目描述中所有的限制,否则,你将会得到 $0$ 分。

输入输出样例

输入样例 #1

0
4
4
kdoi
7
ccccccc
7
sszcdjr
7
abacaca

输出样例 #1

Huoyu
2
2 1 2
2 3 4
Shuiniao
Huoyu
3
3 1 2 3
2 4 5
2 6 7
Huoyu
3
2 1 4
3 2 3 5
2 6 7

说明

**【样例 1 解释】** 对于第一组测试数据,显然输出构成一个合法的子序列划分,并且 - 对于第一个子序列,$t=\tt{kd}$ 不是回文的; - 对于第二个子序列,$t=\tt{oi}$ 不是回文的。 故这是一组合法的输出。可以证明,对于这组测试数据,$2$ 是 $k$ 的最大可能值。 对于第二组数据,它的任意一个子序列都是回文的, 故显然不存在合法的划分方案。 **【样例 2】** 见选手目录下的 `anti/anti2.in` 与 `anti/anti2.ans`。 这个样例共有 $10$ 组数据,均满足 $n=1\,000$。其中第 $1\sim 3$ 组数据满足特殊性质 A,第 $4\sim 6$ 组数据满足特殊性质 B。 *** **【评分方式】** 本题共有 $20$ 个测试点,每个测试点满分 $5$ 分。 本题采用自定义校验器(special judge)评测。每组测试数据可能有多组解,你只需要给出**任意**一组。 在每个测试点中,你的得分是在所有测试数据上得分的最小值。对于每组测试数据: - 如果你错误地判断了是否有解或者给出了一组不合法的序列,你将会获得 $0$ 分; - 如果你正确判断了是否有解,并在有解时给出了一组合法的序列: - 如果 $k$ 的值不是最大的,你将会获得 $2$ 分; - 如果 $k$ 的值是最大的,你将会获得 $5$ 分。 *** **【数据范围】** 对于全部的测试数据,保证: - $1\le q\le 10$; - $1\le n\le 10^5$; - $s$ 中仅包含小写英文字母。 |测试点|$n\le$|特殊性质| |:--:|:--:|:--:| |$1,2$|$5$|无| |$3\sim 5$|$18$|无| |$6\sim 8$|$1\,000$|B| |$9\sim 11$|$1\,000$|无| |$12\sim 14$|$10^5$|A| |$15\sim 17$|$10^5$|B| |$18\sim 20$|$10^5$|无| - 特殊性质 A:保证 $n$ 是偶数,且 $s$ 中每个字符的出现次数都不超过 $\frac{n}{2}$; - 特殊性质 B:保证 $s$ 中仅有 `a` 和 `b`。 *** **【如何使用校验器】** 为了方便选手测试,在附件的 `anti` 目录下我们下发了 `checker.cpp` 文件作为样例校验器,选手可以编译该程序,并使用它校验自己的输出文件的结果是否**合法**。但请注意它与最终评测时所使用的校验器并不完全一致。你也不需要关心其代码的具体内容。 编译命令为: ```sh g++ -o checker -std=c++14 -O2 checker.cpp ``` `checker` 的使用方式为: ```sh checker <input-file> <output-file> ``` 其中,参数 ` <input-file>` 与 `<output-file>` 依次表示输入文件与你的输出文件。 若你的输出中的数字大小范围不合法,则校验器会给出相应提示并立即退出。否则,校验器输出以下内容: - 在第 $i$ 行 $(1\le i\le q)$ 中,输出第 $i$ 组测试数据的详细提示信息; - 在第 $(q+1)$ 行,输出这个测试点的总结信息。 例如,对于样例 1 的输入与输出,校验器将会向屏幕打印如下内容: ```plain Test case 1: OK. Participant's answer is YES (Huoyu), and k=2. Test case 2: OK. Participant's answer is NO (Shuiniao). Test case 3: OK. Participant's answer is YES (Huoyu), and k=3. Test case 4: OK. Participant's answer is YES (Huoyu), and k=3. ok 4 / 4 test cases passed. (4 test cases) ``` 若将输出改为如下: ```plain Huoyu 2 2 1 2 2 3 4 Huoyu 1 7 1 2 3 4 5 6 7 Huoyu 3 3 1 2 3 2 4 5 2 6 7 Huoyu 3 2 1 4 3 2 3 5 2 6 7 ``` 则会向屏幕打印如下内容: ```plain Test case 1: OK. Participant's answer is YES (Huoyu), and k=2. Test case 2: Wrong answer. The string t obtained in the subsequence a[1] is palindrome. Test case 3: OK. Participant's answer is YES (Huoyu), and k=3. Test case 4: OK. Participant's answer is YES (Huoyu), and k=3. wrong answer 3 / 4 test cases passed. ``` **请注意:** 样例校验器只会检查你的输出是否合法,而**不会**: - 检查有解性是否判断正确; - 检查 $k$ 是否被最大化。 例如,将样例 1 的输出改为如下: ```plain Shuiniao Shuiniao Shuiniao Shuiniao ``` 此时,样例校验器仍会返回 `ok` 的检查结果。