CF319D 题解
2024-10-20 15:50:33
题意
给你一个字符串 \(S\),要求你每次找到一个最短的并且最左边的形如 \(XX\)(即由两个相同的字符串拼接而成)的子串,然后把这个字符串从 \(XX\) 变成 \(X\)。问无法操作后的字符串是什么?
\(|S|\le5\times 10^4\)。
题解
首先有一个重要的结论是:设每次删去的串 \(XX\) 长为 \(2\times len\),则 \(len\) 是递增的。
因为如果将 \(XX\) 替换成 \(X\) 后出现更小的 \(len\),则其必包含 \(X\) 的前缀或后缀。而实际上这部分也被包含于 \(XX\)。故矛盾。
于是我们可以从小到大枚举 \(len\),每次删去长度为 \(2 \times len\) 的。复杂度为 \(O(n^2)\)。
但这还不够。有什么方法更优呢?
注意到如果每次能够 \(O(1)\) 判断当前 \(len\) 能否删,复杂度是 \(O(n \sqrt n)\) 的。因为 \(len\) 递增,所以能删的 \(len\) 不超过 \(\sqrt n\) 个。
如何快速判断是否有长度为 \(2 \times len\) 的 \(XX\)?这里需要用到一个强大的 trick。
每 \(len\) 个单位设置一个观察点,对每相邻两个观察点求 \(lcp\) 与 \(lcs\)。如果存在两个相邻的观察点的 \(lsp+lcs>len\),那么就存在。
证明不难。实际上这个方式判断的是长度 \(\ge 2 \times len\) 的 \(XX\),但因为我们从小到大枚举,故等价。
这样判断的复杂度是 \(O(n\log^2n)\) 的。足以通过此题。
最新文章
- Hibernate @OneToMany等注解设置查询过滤条件等
- 如何在IIS7/7.5上配置IISADMPWD
- Server Tomcat v7.0 Server at localhost was unable to&;nbs 报错问题解决
- php对uploads文件的处理问题的解决
- PDF 补丁丁 0.4.2.950 测试版发布:按文件夹合并生成单独的PDF文件
- (转)SQL Server 2005 中的计算字段
- openwrt使用3G上网卡
- 《UNIX网络编程》之read_timeout实验
- 玩转Web之JavaScript(二)-----javaScript语法总结(二) 涉及Date与数组的语法
- 分布式缓存技术memcached学习系列(四)—— 一致性hash算法原理
- 对redux的理解
- C语言结构体定义的几种方法
- POP3和imap
- object类和内部类
- ionic 在windows环境下更换logo和加载图片的问题
- 异常: Call From * 9000 failed on connection exception: java.net.ConnectException: Connection refused: no further information; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused
- Navicat for MySQL 12中文版 破解流程
- oracle索引分类
- MySQL的SQL语句
- H5填坑笔记--持续更新