专栏文章

T650740 字典序

题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miodglrj
此快照首次捕获于
2025/12/02 17:24
3 个月前
此快照最后确认于
2025/12/02 17:24
3 个月前
查看原文

题目链接

题意

给定两个长度为 nn 的小写字符串 sstt,你可以交换 ss 中相邻两个字符若干次,使得 ss 字典序小于 tt,求最小的交换次数,无解输出 1-1

各部分分

测试点 1

注意到 sstt 不可能通过交换满足条件,故无解输出 1-1 。得到 5 pts。

测试点 10~12

考虑 s1s_1,由于 tt 中所有字母都与 s1s_1 不同,我们遍历 tt 的所有字母,直到找到第一个 ti<s1t_i \lt s_1,如果找到,则 i1i - 1 即为答案,否则即为 1-1。得到 15 pts。

测试点 2~9

可以开始优雅地暴力了。暴力方法有很多,讲一种与正解有关的方法。考虑枚举交换结束后公共前缀(LCP)的长度 lenlen,则每次枚举可以遍历 ss,找到最小的一个字母并将其交换回来。这时,将找到的最小字母 smins_{min}tit_i 比较。若小于,则交换后计算答案输出;若大于,则答案为 1-1 ,也能直接输出;若相等,则继续遍历下一个 lenlen。时间复杂度 O(n2)O(n^2)

正解

考虑优化上面的暴力。可以发现每次只需要每个字母最靠前的一个,所以可以使用 26 个队列 qazq_{'a'-'z'} 来存储字母的位置。同时我们不能再完整地模拟所有交换操作,注意到可以记录 sis_i 后面有 sumisum_i 个在它之前已经被使用(即成为 LCP 的一部分),则在 sis_i 被使用时的真实下标即为 i+sumii + sum_i
所以我们用树状数组记录后缀和 sumsum,从 00 枚举 LCP 长度 lenlen,根据 tlen+1t_{len + 1} 选择取 qc(c[a,tlen+1))q_c(c\in['a', t_{len + 1})) 的队头出来,取下标最靠前的计算需要的移动次数,得出答案当前 lenlen 的答案。然后考虑移动 ssqtlen+1q_{t_{len + 1}} 队头所示位置的字母到 lenlen 处,并弹出 qtlen+1q_{t_{len + 1}} 的队头,同时在树状数组中将该位置加 11。时间复杂度 O(nΣ+nlogn)O(n|\Sigma| + n\log n)Σ|\Sigma| 为字符集大小。

评论

0 条评论,欢迎与作者交流。

正在加载评论...