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]\)结尾的最长回文 ...
随机推荐
- 一套高效的iOS面试题一套高效的iOS面试题
runtime相关问题 runtime是iOS开发最核心的知识了,如果下面的问题都解决了,那么对runtime的理解已经很深了. runtime已经开源了,这有一份别人调试好可运行的源码objc-ru ...
- 20211306丁文博 python技能树、CSDN MarkDown编辑器
测评内容: python技能树.CSDN MarkDown编辑器 指导老师:王志强 班级:2113 学号:20211306 姓名:丁文博 https://blog.csdn.net/weixin_62 ...
- Flutter 新建项目
一.打开VSCode,点击侧边栏扩展按钮,搜索flutter,安装Flutter和Dart 二.按command+shift+P,输入flutter,选择Flutter:New project,新建项 ...
- nkIO方法
import java.util.*; public class Main{ public static void main(String args[]){ Scanner sc = new Scan ...
- 项目自动备份,oracle 自动备份
1 项目备份 变量的形式 定时任务不执行就都写成了绝对路径 #!/bin/bash # # 项目路径 /usr/local/tomcat-bjkjdx 备份文件路径/usr/local/ba ...
- turtle 画照片
# -*- coding: utf-8 -*- import turtle as t import cv2 def draw_img(img_path, scale=1): ""& ...
- AutoCAD_2020_Simplified_Chinese_Win_64bit_dlm
「AutoCAD_2020_Simplified_Chinese_Win_64bit_dlm」https://www.aliyundrive.com/s/zN8zAGgXZ58 点击链接保存,或者复制 ...
- 面向对象程序设计 第二章 C++简单的程序设计
目录 C++语言的特点 1.兼容C语言 · 它保持了C的简洁.高效和接近汇编语言等特点. · 对C的类型系统进行了改革和扩充. · C++也支持面向过程的程序设计,不是一个纯正的面向对象的语言 2.支 ...
- 3dmax专用卸载修复工具,一键完全彻底卸载删除3dmax软件的专用卸载工具
标题:3dmax重新安装方法经验总结,利用卸载清理工具完全彻底排查删除干净3dmax各种残留注册表和文件.3dmax显示已安装或者报错出现提示安装未完成某些产品无法安装的问题,怎么完全彻底删除清理干净 ...
- win 子系统导入centos7
之前在应用商店安装过ubuntu的,有钱的建议从商店购买 window配置 , 准备一个centos系统,我是从已有系统导出的,导出命令 tar -cvf ./centos.tar ./ --excl ...