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]\)结尾的最长回文 ...
随机推荐
- vector 用法2
vector 是向量类型,它可以容纳许多类型的数据,如若干个整数,所以称其为容器.vector 是C++ STL的一个重要成员,使用它时需要包含头文件: 复制代码 代码如下: #include< ...
- JavaScript基础知识整理(引用类型-Date)
Date Date类型可以用来保存时间,保存的日期可以精确到1970年1月1日之后或之前的100000000天. 要创建Date类型对象,可以使用new操作符加构造函数. var now = new ...
- shell相关基础面试题
用sed修改test.txt的23行test为tset: sed –i '23s/test/tset/g' test.txt 查看/web.log第25行第三列的内容. sed –n '25p' /w ...
- SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated
错误提示: SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in ...
- 4、excel快速排序从1开始
在分世界杯的文件时,要求把每一行从1开始排列,自己的做法就是先输入1和2,然后拖黑1和2,接着鼠标一直往下拖,这样就了. 公式的方法: 输入公式=Row()-1,如何在这个单元格的右下角双击就可以了 ...
- AX2012 data() 和 buf2buf()的区别
data() 和 buf2buf()都是AX2012 里面可以选择使用的数据拷贝函数.不同的是data会拷贝原始记录里面的所有字段,包括系统字段(公司,创建人等).而buf2buf在拷贝数据时则不会拷 ...
- 机器学习实战—搭建BP神经网络实现手写数字识别
看了几天的BP神经网络,总算是对它有一点点的理解了.今天就用python搭建了一个模型来实现手写数字的识别. 一.BP神经网络简介 BP(back propagation)神经网络是一种按照误差逆向传 ...
- Centos7部署PXE+Kickstart 实现批量安装操作系统
1.PXE环境概述 作为一名运维人员,在一些中小公司经常会遇到一些机械式的重复工作,比如:批量一次大批量的进行操作系统的安装等等.为了实现自动化运维,减少人员负担我们可以部署以下服务:Kickstar ...
- HashMap长度为什么是2的幂
虽然hash值很多,范围很大,但是内存存不了那么大的数组,所以取hash的散列值的时候,需要用hash值,除以数组长度取余数.又由于取余数(%)的性能不如与运算(&),所以想用与运算来代替取余 ...
- 三,打包electron
1,在当前项目下运行 npm install --save-dev @electron-forge/cli npx electron-forge import 此时package.json内容如下: ...