题意:有两个字符串\(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的更多相关文章

  1. [日记&做题记录]-Noip2016提高组复赛 倒数十天

    写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...

  2. SDOI2016 R1做题笔记

    SDOI2016 R1做题笔记 经过很久很久的时间,shzr终于做完了SDOI2016一轮的题目. 其实没想到竟然是2016年的题目先做完,因为14年的六个题很早就做了四个了,但是后两个有点开不动.. ...

  3. CCPC2018-湖南全国邀请赛 G String Transformation

    G.String Transformation 题目描述 Bobo has a string S = s1 s2...sn consists of letter a , b and c . He ca ...

  4. LCT做题笔记

    最近几天打算认真复习LCT,毕竟以前只会板子.正好也可以学点新的用法,这里就用来写做题笔记吧.这个分类比较混乱,主要看感觉,不一定对: 维护森林的LCT 就是最普通,最一般那种的LCT啦.这类题目往往 ...

  5. java做题笔记

    java做题笔记 1. 初始化过程是这样的: 1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化: 2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序 ...

  6. NOIP做题练习(day2)

    A - Reign 题面 题解 最大子段和+\(DP\). 预处理两个数组: \(p[i]\)表示 \(i\) 之前的最大子段和. \(l[i]\)表示 \(i\) 之后的最大子段和. 最后直接输出即 ...

  7. SAM 做题笔记(各种技巧,持续更新,SA)

    SAM 感性瞎扯. 这里是 SAM 做题笔记. 本来是在一篇随笔里面,然后 Latex 太多加载不过来就分成了两篇. 标 * 的是推荐一做的题目. trick 是我总结的技巧. I. P3804 [模 ...

  8. UOJ 做题记录

    UOJ 做题记录 其实我这么弱> >根本不会做题呢> > #21. [UR #1]缩进优化 其实想想还是一道非常丝播的题目呢> > 直接对于每个缩进长度统计一遍就好 ...

  9. C语言程序设计做题笔记之C语言基础知识(下)

    C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...

随机推荐

  1. ubuntu安装rvm

    sudo apt-get install curl git-core bash -s stable < <(curl -s https://raw.github.com/wayneeseg ...

  2. github常见错误提示之一

    如果输入$ Git remote add origin git@github.com:Jomsou(github帐号名)/gitdemo(项目名).git 提示出错信息:fatal: remote o ...

  3. rpgmakermv(8) XY_TitleMenu插件

    插件作用:设置标题 /*: * @plugindesc v1.00 Display Multiple Menu in Title Screen. * @author XueYu Plugins * * ...

  4. Ontology Relations

    Overview The following page documents the relations used in the filtered GO ontology. For informatio ...

  5. xmldecoder漏洞

    https://blog.csdn.net/youanyyou/article/details/78990312

  6. flask设置cookie,设置session,模拟用户认证、模拟管理后台admin、模拟用户logout

    设置cookie HTTP协议是无状态的,在一次请求响应结束后,服务器不会留下关于客户端状态的信息.但是对于某些web程序来说,客户端的信息有必要被记住,比如用户的登录状态,这样就可以根据用户的状态来 ...

  7. 证券化代币的时代已经到来,STO将引爆区块链经济

    STOs 似乎会在 2019 年取代 ICOs,即使不是完全取代,但置换的比例也会相当大.所有在美上市的公司都将按照 SEC 制定的相关规定进行交易.Vellum Capital 的 CEO 兼管理合 ...

  8. 加密对象到locastorage / 从 locastorage解密对象

    var obj={name:"致远",age:21,address:"江西上饶XXXX",hobby:"看书,编程"};//用中文 记得加e ...

  9. tomcat9 性能调优

    官网最靠谱 tomcat 参数官网: http://tomcat.apache.org/tomcat-7.0-doc/config/http.html   <Connector   port=& ...

  10. [转载]window.location.href的用法(动态输出跳转)

    无论在静态页面还是动态输出页面中window.location.href都是不错的用了跳转的实现方案   javascript中的location.href有很多种用法,主要如下. self.loca ...