#B4369. [语言月赛 202507] LZW 压缩

[语言月赛 202507] LZW 压缩

题目描述

LZW 压缩是一种非常著名且广泛使用的无损数据压缩算法。

以下是 LZW 压缩算法的流程:

  1. 给定一个输入字符串 SS 和初始字典D^\dag D,设字符串 PP 为空串。
  2. 获取 SS 中未被遍历的第一个字符 cc
    • P+cP+c(加号表示字符串连接)存在于字典中,则令 P=P+cP=P+c,重复执行第 2 步。
    • 否则,将 P+cP+c 添加到字典 DD,其对应的编码为 DD 中元素的个数加一。输出 PP 代表的编码,令 P=cP=c,重复执行第 2 步。
  3. 最后,输出 PP 代表的编码。

\dag:在本题中,字典 DD 是一个结构体数组。其中,每个结构体内存储了两个变量 S,xS,x,意为正整数编码 xx 可以代表字符串 SS

例如,对字符串 ABABABA 进行 LZW 压缩的流程如下:

初始字典 DD{A,1},{B,2}\{{\tt A},1\},\{{\tt B},2\}

PP cc P+cP+c P+cP+c 是否在 DD 输出 新增字典条目 PP 更新为
空串 A A
A B AB 11 {AB,3}\{\texttt{AB},3\} B
B A BA 22 {BA,4}\{\texttt{BA},4\} A
A B AB AB
AB A ABA 33 {ABA,5}\{\texttt{ABA},5\} A
A B AB AB
AB A ABA ABA
ABA 结束 55

ABABABA 的 LZW 压缩结果为 1 2 3 5

现给出字符串 SS 和初始字典 DD,请对 SS 进行 LZW 压缩,并输出执行完 LZW 压缩后的字典。

输入格式

第一行输入三个整数 n,k,sn,k,s,表示字符串 SS 的长度、初始字典 DD 的大小,且字符集为前 ss 个大写英文字母。

接下来 kk 行,每行输入一个字符串,表示字典中的一个条目,输入的第 ii 个字符串对应的编号为 ii。保证前 ss 个大写英文字母一定在字典中出现,且这 ss 个条目一定是前 ss 个给出的。

接下来一行一个字符串 SS

输出格式

第一行输出若干个由空格分隔的正整数,表示 SS 经 LZW 压缩后的结果。

第二行输出一行一个正整数 kk,表示字典 DD 的大小。

接下来 kk 行,每一行输出一个字符串,表示字典 DD 的各个条目。你应当按编号从小到大的顺序输出,即你输出的第 ii 个字符串对应的编号应为 ii

7 2 2
A
B
ABABABA
1 2 3 5
5
A
B
AB
BA
ABA
25 1 1
A
AAAAAAAAAAAAAAAAAAAAAAAAA
1 2 3 4 5 6 4
7
A
AA
AAA
AAAA
AAAAA
AAAAAA
AAAAAAA
19 6 6
A
B
C
D
E
F
ACBECDFCAACBECDACBE
1 3 2 5 3 4 6 3 1 7 9 11 16 5
19
A
B
C
D
E
F
AC
CB
BE
EC
CD
DF
FC
CA
AA
ACB
BEC
CDA
ACBE

提示

样例 1 解释

此样例即为题目描述中的例子。

注意在输出字典的条目时,需要将输入的字典条目一并输出。

样例 2 解释

此样例满足特殊性质 AB。

数据范围与约定

对于全部数据,满足 1n,k3000,1s261\le n,k\le 3000, 1\le s\le 26DD 中所有字符串的长度总和不超过 nn,且 DD 中没有重复的字符串。保证前 ss 个大写英文字母一定在字典中出现,且这 ss 个条目分别使用编码 1s1\sim s。各测试点的详细数据范围见下表。

测试点 n,kn,k 特殊性质
131\sim 3 600\le 600 A
474\sim 7 1000\le 1000
898\sim 9 2000\le 2000 B
101310\sim 13 C
141714\sim 17
182018\sim 20 3000\le 3000

特殊性质 A:保证 s=1s=1

特殊性质 B:保证 k=sk=s

特殊性质 C:保证字符串 ss 为随机生成。