1 条题解
-
0
「POI2011 R3」周期性 Periodicity 题解
题目简述
给定一个大写字母串(人名),要求把它转换为同样长度的 串,且满足:
长度相同
与原串有相同的周期集合
字典序最小
如果无解则输出 XXX。
什么是周期? 对于长度为 的字符串 ,一个整数 是周期,当且仅当对于所有 ,都有 。
即前 个字符和后 个字符完全匹配。
核心思想
关键性质
字符串的周期集合完全由其前缀函数或 KMP 的 fail 数组决定。
具体来说,字符串 的长度为 , 表示 的最长相同真前缀后缀长度。则 是 的周期 ⇔ 在 数组的值中(或者说 )。
所以问题转化为 给定 数组,构造字典序最小的 串,使其 数组与给定相同。
算法步骤
- 先判断可行性 并不是所有 数组都能对应一个合法字符串。需要检查:
对于 ,要么 ,要么 ,要么 且有对应的字符匹配关系。
实际上更简单的方法:如果 ,则 。
所以我们可以推导出原字母串中哪些位置的字符必须相同,把它们分组。
- 构造最小字典序 串 我们从左到右构造:
设现在处理到第 位
如果 ,则 必须等于 ,直接复制过来
如果 ,我们可以自由选择 。为了字典序最小,我们总是先尝试填 0,如果填 0 会导致后面某个位置矛盾(即导致 数组不对),才填 1
-
判断矛盾 填完 后,要更新它对后续位置 值的影响。 更具体地说,当我们确定了 ,要检查所有 的 是否满足 (如果 时)。若不满足且 已经确定,则无解。
-
用并查集维护相同关系 把必须相同的字符位置用并查集合并。在尝试填 0 时,如果该位置的集合已经固定为 1,则不能填 0。
具体算法
读取原字母串,忽略具体字母,只根据相同字母出现模式得到哪些位置必须相同
即如果原串中 ,则在新 串中位置 和 必须同字符(0 或 1 相同)
如果 ,则位置 和 必须不同
实际上我们不必依赖原字母,而是根据 fail 数组推导等价关系。
通过 KMP 算法得到原串的 fail 数组 。
从 到 构造:
如果 ,则
如果 ,则尝试填 0,判断是否矛盾;矛盾则填 1,再判断是否矛盾;都矛盾则无解(输出 XXX)
输出构造的 串。
复杂度分析
计算 fail 数组:
构造答案并查集维护:
总复杂度:
- 1
信息
- ID
- 5924
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者