贴个题目链接:https://www.luogu.org/problem/P4555

题目:输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(∣X∣,∣Y∣≥1)且X和Y都是回文串。

输入输出样例

输入 #1
baacaabbacabb
输出 #1
12

说明/提示

【样例说明】

从第二个字符开始的字符串aacaabbacabb可分为aacaabbacabb两部分,且两者都是回文串。

思路,我们的回文自动机每次加进去一个字符都会更新last,last就是以这个字符为结尾能得到的最长回文串的节点号,那我们直接开个ans数组记录一下len【last】就是表示以这个字符为结尾的最长回文串长度。

搞两个回文树,一个正着跑,一个倒着跑,那么我们就可以ans1【i】+ans2【i+1】表示的意思就是以s【i】为X结尾,s【i+1】为Y开头(因为这个是倒着跑的,正着看就是以它为开头)最回文大长度。

#include <bits/stdc++.h>
#define met(a, b) memset(a, b, sizeof(a))
#define ll long long
#define ull unsigned long long
using namespace std; const int maxn = 100005;
const int N = 26;
struct PAM{
int ne[maxn][N];//next指针,next指针和字典树类似,指向的串为当前串两端加上同一个字符构成
int fail[maxn];//fail指针,失配后跳转到fail指针指向的节点
int cnt[maxn]; //表示节点i表示的本质不同的串的个数(建树时求出的不是完全的,最后count()函数跑一遍以后才是正确的)
int num[maxn]; //表示以节点i表示的最长回文串的最右端点为回文串结尾的回文串个数
int len[maxn];//len[i]表示节点i表示的回文串的长度(一个节点表示一个回文串)
int S[maxn] ;//存放添加的字符
int last ;//指向新添加一个字母后所形成的最长回文串表示的节点。
int n;//表示添加的字符个数。
int p;//表示添加的节点个数。
int ans[maxn];//以st【i】为结尾的最长回文子串的长度
int newnode(int l){ //新建节点
for(int i = 0; i < N; i++) ne[p][i] = 0;
cnt[p] = num[p] = 0;
len[p] = l;
return p++;
}
void init(){ //初始化
p = 0;
newnode(0);
newnode(-1);//顺序不能反
last = 0;
n = 0;
S[n] = -1; //防止越界
fail[0] = 1;
}
int get_fail(int x){
while(S[n - len[x] - 1] != S[n]) x = fail[x];
return x;
}
void add(int c){
c = c - 'a';
S[++n] = c;
int cur = get_fail(last);//通过上一个回文串找这个回文串的匹配位置
if(!ne[cur][c]){//如果这个回文串没有出现过,说明出现了一个新的本质不同的回文串
int now = newnode(len[cur] + 2);//新建节点
fail[now] = ne[get_fail(fail[cur])][c];//和AC自动机一样建立fail指针,以便失配后跳转
ne[cur][c] = now;
num[now] = num[fail[now]] + 1;
}
last = ne[cur][c];
ans[n] = len[last];
cnt[last]++;
}
void count_cnt(){
for(int i = p-1; i >= 0; i--){
cnt[fail[i]] += cnt[i]; //父亲累加儿子的cnt,因为如果fail[v]=u,则u一定是v的子回文串!
}
}
}pam1, pam2; char st[maxn];
int arr[10005];
int main(){
scanf("%s",st);
pam1.init();
pam2.init();
int len = strlen(st);
for(int i = 0; i < len; i++)
pam1.add((int)st[i]);
for(int i = len-1; i >= 0; i--)
pam2.add((int)st[i]);
pam1.count_cnt();
pam2.count_cnt();
int ma = 0;
for(int i = 1; i < len; i++){
ma = max(ma, pam1.ans[i] + pam2.ans[len-i]);
}
cout << ma << endl;
return 0;
}

P4555 [国家集训队]最长双回文串 回文树(回文自动机)简单题的更多相关文章

  1. P4555 [国家集训队]最长双回文串

    P4555 [国家集训队]最长双回文串 manacher 用manacher在处理时顺便把以某点开头/结尾的最长回文串的长度也处理掉. 然后枚举. #include<iostream> # ...

  2. 洛谷 P4555 [国家集训队]最长双回文串 解题报告

    P4555 [国家集训队]最长双回文串 题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为\(n\)的串 ...

  3. Manacher || P4555 [国家集训队]最长双回文串 || BZOJ 2565: 最长双回文串

    题面:P4555 [国家集训队]最长双回文串 题解:就.就考察马拉车的理解 在原始马拉车的基础上多维护个P[i].Q[i]数组,分别表示以i结尾最长回文子串的长度和以i开头的最长回文子串的长度 然后就 ...

  4. 【洛谷】P4555 [国家集训队]最长双回文串

    P4555 [国家集训队]最长双回文串 题源:https://www.luogu.com.cn/problem/P4555 原理:Manacher 还真比KMP好理解 解决最长回文串问题 转化为长度为 ...

  5. P4555 [国家集训队]最长双回文串(回文树)

    题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为 n 的串 S ,求 S 的最长双回文子串 T ,即可 ...

  6. 洛谷 P4555 [国家集训队]最长双回文串(Manacher)

    题目链接:https://www.luogu.com.cn/problem/P4555 首先明白两个回文串,那么要使两个回文串成立,那么我们只能把$'#'$作为中间节点. 然后我们跑一边Manache ...

  7. 洛谷 P4555 [国家集训队]最长双回文串

    链接: P4555 题意: 在字符串 \(S\) 中找出两个相邻非空回文串,并使它们长度之和最大. 分析: 直接使用马拉车算法求出每个点扩展的回文串.如果枚举两个回文串显然会超时,我们考虑切割一个长串 ...

  8. 洛谷P4555 [国家集训队]最长双回文串(manacher 线段树)

    题意 题目链接 Sol 我的做法比较naive..首先manacher预处理出以每个位置为中心的回文串的长度.然后枚举一个中间位置,现在要考虑的就是能覆盖到i - 1的回文串中 中心最靠左的,和能覆盖 ...

  9. Manacher【p4555】 [国家集训队]最长双回文串

    题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为 n 的串 S ,求 S 的最长双回文子串 T ,即可 ...

  10. 【洛谷 P4555】 [国家集训队]最长双回文串 (Manacher)

    题目链接 \(|S|<=10^5\),时间还是很宽松的. 允许我们使用线性/\(N\log N\)/甚至\(N \sqrt N\)的算法. 设\(l[i]\)表示以\(a[i]\)结尾的最长回文 ...

随机推荐

  1. CSS中Position几种属性的总结

    定位position 定位方向:left  right  top  bottom 静态定位:static  默认值,就是文档流 绝对定位:absolute    特点: 1.不占据原来的位置(脱标) ...

  2. 微信支付宝app支付回调参数

    微信app支付回调通知参数: <xml><appid><![CDATA[wx9703cd*******]]></appid><attach> ...

  3. OPENSSL 生成RSA公钥、私钥和证书

    在命令窗口执行下列操作. 1)生成RSA私钥: openssl genrsa -out rsa_private_key.pem 2048 生成内容: -----BEGIN RSA PRIVATE KE ...

  4. ORA-00972: identifier is too long异常处理

    环境:由于数据库更换,做数据同步,提示 too long 问题,导致一直无法同步完数据. 经排查 oracle 历史数据库版本: Oracle Database 12c Standard Editio ...

  5. SpringIOC以及AOP注解开发

    和 XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作. 本质上:所有一切的操作都是 Java ...

  6. java不返回某些字段,包括 null

    一.使用 fastjson 包. (1) SimplePropertyPreFilter 可以将需要的字段留下来. import com.alibaba.fastjson.JSON;import co ...

  7. FCC 高级算法题 验证电话号码

    Validate US Telephone Numbers 如果传入字符串是一个有效的美国电话号码,则返回 true. 用户可以在表单中填入一个任意有效美国电话号码. 下面是一些有效号码的例子(还有下 ...

  8. Java定时器Timer和TimerTask

    方式一:设定指定任务task在指定时间time执行 schedule(TimerTask task, Date date)   public static void main(String[] arg ...

  9. 【js】js执行机制-js单线程-同步和异步

    js是单线程 即同一个时间只能做一件事,JavaScript是为处理页面中用户的交互,以及操作DOM而诞生的.比如我们对某个DOM元素进行添加和删除操作,不能同时进行.应该先进行添加,之后在进行删除. ...

  10. Tomcat总体架构和启动流程

    Tomcat大家都知道,这个没什么好描述的,我们先看Tomcat的总体架构 1.总体架构 架构一步一步增加组件,先来个最原始的 === Server:Tomcat的整体服务,负责接收和处理请求.其拥有 ...