P4555 [国家集训队]最长双回文串 回文树(回文自动机)简单题
贴个题目链接:https://www.luogu.org/problem/P4555
题目:输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(∣X∣,∣Y∣≥1)且X和Y都是回文串。
输入输出样例
baacaabbacabb
12
说明/提示
【样例说明】
从第二个字符开始的字符串aacaabbacabb可分为aacaa与bbacabb两部分,且两者都是回文串。
思路,我们的回文自动机每次加进去一个字符都会更新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 [国家集训队]最长双回文串 回文树(回文自动机)简单题的更多相关文章
- P4555 [国家集训队]最长双回文串
P4555 [国家集训队]最长双回文串 manacher 用manacher在处理时顺便把以某点开头/结尾的最长回文串的长度也处理掉. 然后枚举. #include<iostream> # ...
- 洛谷 P4555 [国家集训队]最长双回文串 解题报告
P4555 [国家集训队]最长双回文串 题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为\(n\)的串 ...
- Manacher || P4555 [国家集训队]最长双回文串 || BZOJ 2565: 最长双回文串
题面:P4555 [国家集训队]最长双回文串 题解:就.就考察马拉车的理解 在原始马拉车的基础上多维护个P[i].Q[i]数组,分别表示以i结尾最长回文子串的长度和以i开头的最长回文子串的长度 然后就 ...
- 【洛谷】P4555 [国家集训队]最长双回文串
P4555 [国家集训队]最长双回文串 题源:https://www.luogu.com.cn/problem/P4555 原理:Manacher 还真比KMP好理解 解决最长回文串问题 转化为长度为 ...
- P4555 [国家集训队]最长双回文串(回文树)
题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为 n 的串 S ,求 S 的最长双回文子串 T ,即可 ...
- 洛谷 P4555 [国家集训队]最长双回文串(Manacher)
题目链接:https://www.luogu.com.cn/problem/P4555 首先明白两个回文串,那么要使两个回文串成立,那么我们只能把$'#'$作为中间节点. 然后我们跑一边Manache ...
- 洛谷 P4555 [国家集训队]最长双回文串
链接: P4555 题意: 在字符串 \(S\) 中找出两个相邻非空回文串,并使它们长度之和最大. 分析: 直接使用马拉车算法求出每个点扩展的回文串.如果枚举两个回文串显然会超时,我们考虑切割一个长串 ...
- 洛谷P4555 [国家集训队]最长双回文串(manacher 线段树)
题意 题目链接 Sol 我的做法比较naive..首先manacher预处理出以每个位置为中心的回文串的长度.然后枚举一个中间位置,现在要考虑的就是能覆盖到i - 1的回文串中 中心最靠左的,和能覆盖 ...
- Manacher【p4555】 [国家集训队]最长双回文串
题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为 n 的串 S ,求 S 的最长双回文子串 T ,即可 ...
- 【洛谷 P4555】 [国家集训队]最长双回文串 (Manacher)
题目链接 \(|S|<=10^5\),时间还是很宽松的. 允许我们使用线性/\(N\log N\)/甚至\(N \sqrt N\)的算法. 设\(l[i]\)表示以\(a[i]\)结尾的最长回文 ...
随机推荐
- JS篇(002)-JavaScript 中如何检测一个变量是一个 String 类型?
答案:三种方法(typeof.constructor.Object.prototype.toString.call()) 解析: ①typeof typeof('123') === "str ...
- Pytest Fixture(一)
Fixture 是一些函数,pytest 会在执行测试函数之前(或之后)加载运行它们.我们可以用它做一些事情,比如数据库的链接操作之类的 import pytest @pytest.fixture() ...
- 实验:STM32F103烧写支持Arduino
1.搭建烧写环境 烧写器:ST-LINK. 2.启动stm32 flash烧写工具 3.连接识别CPU 4.打开generic-boot20_pc13.bin 5.烧写程序 6.查上miniUS ...
- 项目实训DAY 11-12 学习
在神经网络可视化工具中,选择了三种,NNSVG,PlotNeuralNet,GraphCore 前两者应该比较好实现,例子都跑通了,对于定制的代码读起来也不难.PNN的示例图如下 最后一个虽然有实例图 ...
- spring security添加接口白名单
在项目中遇到的问题是要将某个接口设为白名单,无需验证即可被用户使用. 解决方法: 在nacos配置文件中ignore whites(不校验白名单)中添加对应接口,无gateway前缀即可,添加立即生效 ...
- 最短路算法之 Dijkstra
部分内容参考了李煜东的<算法竞赛进阶指南>,在此声明. 单源最短路径 单源最短路径问题,是说,给定一张有向图(无向图)\(G=(V,E)\) ,\(V\) 是点集,\(E\) 是边集,\( ...
- Elasticsearch 查询小笔记
2.x 版本,组合多查询https://www.elastic.co/guide/cn/elasticsearch/guide/current/combining-queries-together.h ...
- js中函数(方法)注释
原文链接:https://blog.csdn.net/tianxintiandisheng/article/details/103764074 实例 /** * @function 处理表格的行 * ...
- CMMI的软件工程13-16章读书笔记
一.软件测试 软件测试是为了发现程序中的错误而执行的过程.测试只能证明软件有错,而不能保证软件程序没错. 1. 软件版本 Alpha版 公司内测版本 Beta版 对外公测版本 发布版 正式发布版本 ...
- Windows server 防火墙开放oracle监听端口
Windows server 防火墙开放oracle监听端口 Windows server 2008 开放1521端口 Windows server 2003 开放监听程序例外先开防火墙,再开监听例外 ...