Petya 在他自己开发的编程语言 Tse 中实现了一个用于动态内存分配的堆。以下是它的工作原理。
一个正确的堆是一个由 $N$ 个单元组成的连续内存段。每个单元包含一个无符号 8 位整数,其值在 $0$ 到 $255$ 之间(含 $0$ 和 $255$)。堆被划分为 $B$ 个称为“块”(blocks)的子段。每个内存单元严格属于一个块。
每个块由两个或更多单元组成。块的第一个和最后一个单元包含该块的“有效大小”(effective size),即该块中除第一个和最后一个单元之外的单元数量。块中的其余单元可以包含任意数据,无论该块是空闲的还是被占用的。
Tse 是一种非常低级的语言,其用户经常会把事情搞砸,因不小心将数据写入错误的单元而损坏堆。用户要求 Petya 提供一个在发生此类事件后恢复堆完整性的功能。恢复代码必须分析堆所在的内存段的 $N$ 个单元的内容,并修改若干个内存单元的内容,使得该段成为一个正确的堆。修改的单元数量必须最少。
输入格式
包含被分析内存段的 $N$ 个内存单元的内容,以大小为 $N$ 字节的二进制文件形式提供。文件中的每个字节代表一个内存单元。满足 $2 \le N \le 2^{24}$,这意味着文件的大小不小于 2 字节且不大于 16 兆字节。
输出格式
将找到的包含 $K$ 个单元修改的集合写入一个大小为 $4K$ 字节的二进制文件中。
每个修改由四个字节描述。前三个字节被视为一个无符号 24 位整数,定义了被修改单元的地址(索引)。显然,这个数字必须小于 $N$ —— 即输入文件的大小。最后一个(第四个)字节定义了该单元的新内容。
24 位地址必须以小端(little-endian)字节序写入,即第一个字节是最低有效字节,最后一个字节是最高有效字节。如果有多个具有相同修改数量的答案,你可以输出其中任意一个。输出文件中描述单元修改的顺序无关紧要。
样例
为了方便起见,下面以十六进制(hex)格式显示输入和输出文件的内容。在评测系统中,文件将是二进制格式!你可以在题目旁边的“News”标签页中下载二进制格式的样例。
对于快速文件读取,建议在 Java 中使用一次 Files.readAllBytes 调用,在 C++ 中使用 fread。不要忘记在 C++ 中应以二进制模式打开文件。
输入样例 1
02 AA BB 02 00 00 03 AB AC AD 03
输出样例 1
输入样例 2
02 AA BB CC 00 DD 03 AB AC AD 03
输出样例 2
03 00 00 02 05 00 00 00
说明
在两个样例中,$N = 11$。
在第一个样例中,堆已经是正确的,包含三个块,其有效大小分别为 $2$、$0$ 和 $3$。由于不需要任何修改,输出文件必须为空。
在第二个样例中,堆是不正确的,但可以通过两次修改来修复,使其完全变成第一个样例中的堆。为此,建议将地址为 $3$ 的单元从 CC 修改为 02,将地址为 $5$ 的单元从 DD 修改为 00。
第二个样例的图解(整数以十进制格式显示)