【做题】CF119D. String Transformation——KMP
题意:有两个字符串\(a,b\),下标从\(0\)开始。求数对\((i,j)\)满足\(a[i+1:j] + r(a[j:n]) + r(a[0:i+1]) = b\),其中\(r(s)\)表示字符串\(s\)的反串。若有多组解,输出其中\(i\)最大,然后\(j\)尽可能小的一组。
\(|a|,|b| \leq 10^6\)
首先考虑枚举\(i\)。那么,我们就要让\(a[i+1:j] + r(a[j:n]) = b[0:n-i-1]\)。因此,前面的\(a[i+1:j]\)必须是\(b\)的一个前缀。这个限制比较简单,求出最长公共前缀后,就可以转化为\(j \leq r\)的形式。
接下来,我们得满足\(r(a[j:n])\)是\(b[0:n-i-1]\)的一个后缀。并且,我们只要求出满足这个条件的最小的\(j\)就可以了。也就是求出\(a\)最长的后缀,它在翻转后也是\(b[0:n-i-1]\)的后缀。这个问题比较复杂,要进行化简。先解决翻转。记\(a_r\)为\(a\)的反串,那么,问题就成为求最长的\(a_r\)的前缀,它也是\(b[0:n-i-1]\)的后缀。开始于一个固定位置的前缀,结束于多个不同位置的后缀。仔细一想的话,这正是KMP中nex数组的定义。因此,我们把\(a_r\)和\(b\)连起来(分隔符还是要加的),求一遍nex数组就可以了。
顺便一提,最长公共前缀必须用EXKMP来求,不然会T。
时间复杂度\(O(n)\)。
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
char a[N],b[N],s[N << 1];
int nex[N << 1],n,pre[N << 1],pw[N],ans1,ans2;
int main() {
cin.getline(a+1,N);
cin.getline(b+1,N);
if (strlen(a+1) != strlen(b+1)) {
puts("-1 -1");
return 0;
}
n = strlen(a+1);
for (int i = 1 ; i <= n ; ++ i)
s[i] = a[n - i + 1];
s[n+1] = 0;
for (int i = 1 ; i <= n ; ++ i)
s[i + n + 1] = b[i];
nex[0] = -1;
for (int i = 1, j = -1 ; i <= (n << 1) + 1 ; nex[i++] = ++ j)
while (j >= 0 && s[i] != s[j+1]) j = nex[j];
for (int i = 1 ; i <= n ; ++ i)
s[i] = b[i];
s[n+1] = 0;
for (int i = 1 ; i <= n ; ++ i)
s[i + n + 1] = a[i];
pre[1] = 2 * n + 1;
while (s[2 + pre[2]] == s[1 + pre[2]] && 2 + pre[2] <= 2 * n + 1)
++ pre[2];
int p = 2;
for (int i = 3 ; i <= 2 * n + 1 ; ++ i) {
if (pre[i - p + 1] < pre[p] + p - i)
pre[i] = pre[i - p + 1];
else {
int j = max(0,p + pre[p] - i);
while (s[i + j] == s[1 + j] && i + j <= 2 * n + 1)
++ j;
pre[i] = j;
p = i;
}
}
ans1 = ans2 = -1;
for (int i = 1 ; i <= n ; ++ i) {
int r = pre[i + n + 1] + i;
int l = nex[2 * n + 1 - (i-1)];
if (n - l + 1 <= r) ans1 = i - 2, ans2 = n - l;
if (a[i] != b[n-i+1]) break;
}
if (ans1 == -1) ans2 = -1;
printf("%d %d\n",ans1,ans2);
return 0;
}
小结:这道题难度其实不大,但推导过程较长,因此需要时刻保持思路清晰,心态平稳。
【做题】CF119D. String Transformation——KMP的更多相关文章
- [日记&做题记录]-Noip2016提高组复赛 倒数十天
写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...
- SDOI2016 R1做题笔记
SDOI2016 R1做题笔记 经过很久很久的时间,shzr终于做完了SDOI2016一轮的题目. 其实没想到竟然是2016年的题目先做完,因为14年的六个题很早就做了四个了,但是后两个有点开不动.. ...
- CCPC2018-湖南全国邀请赛 G String Transformation
G.String Transformation 题目描述 Bobo has a string S = s1 s2...sn consists of letter a , b and c . He ca ...
- LCT做题笔记
最近几天打算认真复习LCT,毕竟以前只会板子.正好也可以学点新的用法,这里就用来写做题笔记吧.这个分类比较混乱,主要看感觉,不一定对: 维护森林的LCT 就是最普通,最一般那种的LCT啦.这类题目往往 ...
- java做题笔记
java做题笔记 1. 初始化过程是这样的: 1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化: 2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序 ...
- NOIP做题练习(day2)
A - Reign 题面 题解 最大子段和+\(DP\). 预处理两个数组: \(p[i]\)表示 \(i\) 之前的最大子段和. \(l[i]\)表示 \(i\) 之后的最大子段和. 最后直接输出即 ...
- SAM 做题笔记(各种技巧,持续更新,SA)
SAM 感性瞎扯. 这里是 SAM 做题笔记. 本来是在一篇随笔里面,然后 Latex 太多加载不过来就分成了两篇. 标 * 的是推荐一做的题目. trick 是我总结的技巧. I. P3804 [模 ...
- UOJ 做题记录
UOJ 做题记录 其实我这么弱> >根本不会做题呢> > #21. [UR #1]缩进优化 其实想想还是一道非常丝播的题目呢> > 直接对于每个缩进长度统计一遍就好 ...
- C语言程序设计做题笔记之C语言基础知识(下)
C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...
随机推荐
- 如何运行ruby代码
第一种,ruby -e 在命令行中运行下面命令,-e的意思是,把后面的字符串当作脚本执行 ruby -e "print 'hello'" 使用irb交互控制台 在命令行输入irb ...
- Python全栈-day4-语法基础2
一.字符串 1.字符串基础 1)作用:用于描述姓名.性别.地址等信息 2)定义方式:单引号或者双引号以及三引号内添加字符 注:day3中介绍 name = 'zhang' user_name = &q ...
- sql privot 实现行转列
表结构如下: RefID HRMS Name InsuranceMoney InsuranceNamefb2bdee8-e4c9-4470-8e7f-14550d3212f7 ...
- 调用微信JS-SDK配置签名
前后端进行分开开发: 1:后端实现获取 +++接口凭证:access_token (公众号的全局唯一接口调用凭据) ** GET 获取:https://api.weixin.qq.com/cgi-bi ...
- vue去掉严格开发,即去掉vue-cli安装时的eslint
vue去掉严格开发,即去掉vue-cli安装时的eslint : 1.vue-cli书写规范(主要是js规范) a.逗号.冒号后面要加空格 b.不能使用双引号,一律使用单引号 webpack的语法检查 ...
- HDU 2511 汉诺塔X
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2511 1,2,...,n表示n个盘子.数字大盘子就大.n个盘子放在第1根柱子上.大盘不能放在小盘上.在 ...
- python 闭包和装饰器
python 闭包和装饰器 一.闭包闭包:外部函数FunOut()里面包含一个内部函数FunIn(),并且外部函数返回内部函数的对象FunIn,内部函数存在对外部函数的变量的引用.那么这个内部函数Fu ...
- oracel中合并报表的sql
select decode(dt.LATN_ID ,290,'西安','910','咸阳',911,'延安',912,'榆林',913,'渭南',914,'商洛',915,'安康', 916,'汉中' ...
- Zabbix客户端(被监控端)安装配置
1) 创建用户 groupadd zabbix useradd -g zabbix zabbix 2)zabbix软件包下载,安装 zabbix-2.2.6 http://jaist.dl.sourc ...
- PyCharm配置MySQL
有时候电脑没有安装Navicat,也想要操作数据库,那么PyCharm也能实现Navicat的一些功能.下面演示,用PyCharm如何连接数据库并执行操作: 1. 打开PyCharm,在右侧边栏打开D ...