## [$>Codeforces \space 30\ E. Tricky\ and\ Cleve\ Password

题目大意 : 给出一个串 \(S\),让你找出 \(A, B, C\) 三个串,满足 \(C\) 是一个后缀, \(A + B + C\)是一个回文串,\(B\) 是一个长度为奇数的回文串,且 \(A, C\) 可以为空,并最大化 \(|A| + |B| + |C|\)

\(1 \leq |S| \leq 10^5\)

解题思路 :

考虑 \(B\) 是不能为空的,不妨先用 \(Manacher\) 跑一边,然后枚举 \(B\) 的回文中心

那么问题转化为,在 \(B\) 之前的某个子串和在 \(B\) 之后的后缀的反串最长匹配长度

可以 \(KMP\) 出对于每一个 \(i\),\(mx_i\) 表示以 \(i\) 结尾的前缀最长匹配了多长的反串后缀

那么对于回文中心 \(i\), 设其回文半径为 \(r_i\),其作为 \(B\) 串回文中心的答案就是 \(2(p_i+\min(mt[i-r_i], n - i - r_i + 1) - 1\)

所以统计枚举每一个回文中心,\(O(1)\) 统计答案即可,总复杂度是 \(O(n)\),更多内容可以参考 2014年集训队论文 《浅谈回文子串问题 》—— 徐毅

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int f = 0, ch = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
} const int N = 500005;
char s[N];
int pr[N], n;
struct Match{ int l, r, len; } mt[N];
struct Answer{ int l, r, p, su, val; } ans; namespace Manacher{
char t[N]; int r[N], len;
inline void init(char *s){
for(int i = 1; i <= n; i++)
t[++len] = '#', t[++len] = s[i]; t[++len] = '#';
}
inline void realmain(){
int mx = 0, p = 0;
for(int i = 1; i <= len; i++){
if(mx > i) r[i] = Min(r[2*p-i], mx - i); else r[i] = 1;
while(r[i] < i && i + r[i] - 1 <= len && t[i-r[i]] == t[i+r[i]]) ++r[i];
if(i + r[i] - 1 > mx) mx = i + r[i] - 1, p = i;
}
for(int i = 2; i <= len; i += 2) pr[i/2] = r[i] / 2;
}
}
namespace Kmp{
char t[N]; int nxt[N];
inline void init(char *s){
for(int i = 1; i <= n; i++) t[i] = s[n-i+1];
nxt[0] = -1;
for(int i = 1, j = -1; i <= n; nxt[i++] = ++j)
while(t[j+1] != t[i] && ~j) j = nxt[j];
}
inline void realmain(char *s){
for(int i = 1, j = 0; i <= n; i++){
while(t[j+1] != s[i] && ~j) j = nxt[j];
mt[i].len = ++j, mt[i].r = i, mt[i].l = i - j + 1;
}
for(int i = 1; i <= n; i++)
if(mt[i-1].len > mt[i].len) mt[i] = mt[i-1];
}
}
int main(){
scanf("%s", s + 1), n = strlen(s + 1);
Kmp::init(s), Kmp::realmain(s);
Manacher::init(s), Manacher::realmain();
for(int i = 1; i <= n; i++){
int pos = i - pr[i], suf = min(mt[pos].len, n - i - pr[i] + 1);
int res = 2 * (pr[i] + suf) - 1;
if(res > ans.val) ans = (Answer){mt[pos].l, mt[pos].r, i, suf, res};
}
int l1 = ans.l, r1 = ans.r;
int l2 = ans.p - pr[ans.p] + 1, r2 = ans.p + pr[ans.p] - 1;
int l3 = n - ans.su + 1, r3 = n, tot = 3;
r1 = min(r1, l2 - 1), l3 = max(l3, r2 + 1);
if(r1 < l1 || !l1 || !r1) tot--;
if(l3 > r3 || l3 > n || r3 > n) tot--;
cout << tot << endl;
if(l1 <= r1 && l1 && r1) cout << l1 << " " << r1 - l1 + 1 << endl;
cout << l2 << " " << r2 - l2 + 1 << endl;
if(l3 <= r3 && l3 <= n && r3 <= n) cout << l3 << " " << r3 - l3 + 1 << endl;
return 0;
}

Codeforces 30 E. Tricky and Cleve Password的更多相关文章

  1. Codeforces 196 E. Tricky and Cleve Password

    \(>Codeforces \space 196\ E. Tricky\ and\ Cleve\ Password<\) 题目大意 : 给出一个有 \(n\) 个结点,\(m\) 条边的连 ...

  2. 算法训练 Tricky and Clever Password

     算法训练 Tricky and Clever Password   时间限制:2.0s   内存限制:256.0MB      问题描述 在年轻的时候,我们故事中的英雄——国王 Copa——他的私人 ...

  3. 算法笔记_055:蓝桥杯练习 Tricky and Clever Password (Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 在年轻的时候,我们故事中的英雄——国王 Copa——他的私人数据并不是完全安全地隐蔽.对他来说是,这不可接受的.因此,他发明了一种密码,好 ...

  4. 【Codeforces 429D】 Tricky Function

    [题目链接] http://codeforces.com/problemset/problem/429/D [算法] 令Si = A1 + A2 + ... + Ai(A的前缀和) 则g(i,j) = ...

  5. 【codeforces 429D】Tricky Function

    [题目链接]:http://codeforces.com/problemset/problem/429/D [题意] 给你n个数字; 让你求出一段区间[l,r] 使得 (r−l)2+(∑rl+1a[i ...

  6. [CF30E]Tricky and Clever Password(KMP+manacher)

    首先枚举回文中心,然后显然中心两边要尽量扩展作为middle,这个用manacher实现. 然后注意到suffix的结尾位置是固定的(串尾),那么预处理出以每个位置结尾的串与原串后缀至多能匹配多长,然 ...

  7. CF30E. Tricky and Clever Password

    被你谷翻译诈骗了兄弟. 不过下次可以拿去诈骗其他人. 考虑枚举B,显然结论有B作为回文串越长越好,这个可以使用manacher,或者直接二分hash. 然后考虑翻转末尾串,然后记录其匹配到第 \(i\ ...

  8. CentOS6.5 安装mysql5.6.30

    1.下载解压由于系统会自带mysql5.1版本的数据库,需要卸载.[root@localhost src]# yum remove -y mysql-libs[root@localhost src]# ...

  9. docker登录报错Error response from daemon: Get https://192.168.30.10/v1/users/: dial tcp 192.168.30.10:443: connect: connection refused

    背景描述: 登录docker报错: [root@localhost sysconfig]# docker login 192.168.30.10 Username (newcs06): newcs06 ...

随机推荐

  1. jquery 事件对象属性小结

    使用事件自然少不了事件对象. 因为不同浏览器之间事件对象的获取, 以及事件对象的属性都有差异, 导致我们很难跨浏览器使用事件对象. jQuery中统一了事件对象, 当绑定事件处理函数时, 会将jQue ...

  2. 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂

    [题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...

  3. 【BZOJ】1537: [POI2005]Aut- The Bus

    [算法]DP+线段树求区间max(二维偏序) [题解] 状态转移方程:f[i]=max(f[j]+v[i]),x[j]<x[i]&&y[j]<y[i]. 观察j的条件限制显 ...

  4. webpack4 未设置mode会自动压缩

    最近想用LayaBox做个小游戏,然而Laya本身不自带构建工具.然后觉得写模块化的东西还是用webpack好使,用es6的语法也比较清晰. 于是就装了webpack,只用babel-loader来编 ...

  5. Date对象相关函数使用

    参考:http://www.w3school.com.cn/jsref/jsref_obj_date.asp

  6. Java爬虫(二)

    上一篇简单的实现了获取url返回的内容,在这一篇就要第返回的内容进行提取,并将结果保存到html中.而且这个爬虫是基于python爬虫的java语言实现,其逻辑大致相同. 一 . 需求: 抓取主页面: ...

  7. numpy 简介

    .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...

  8. C++ Class与Struct的区别

    转自某楼层的回复http://bbs.csdn.net/topics/280085643 首先,讨论这个问题应该仅从语法上讨论,如果讨论不同人之间编程风格上的差异,那这个问题是没有答案的.毕竟不同的人 ...

  9. Linux运维常用的几个命令介绍【转】

    Linux运维常用的几个命令介绍 1. 查看系统内核版本​ [root@funsion geekxa]# cat /etc/issue CentOS release 6.5 (Final) Kerne ...

  10. $FFT$(快速傅里叶变换)

    - 概念引入 - 点值表示 对于一个$n - 1$次多项式$A(x)$,可以通过确定$n$个点与值(即$x$和$y$)来表示这唯一的$A(x)$ - 复数 对于一元二次方程 $$x^2 + 1 = 0 ...