Solution -「LOJ #141」回文子串 ||「模板」双向 PAM
\(\mathcal{Description}\)
Link.
给定字符串 \(s\),处理 \(q\) 次操作:
- 在 \(s\) 前添加字符串;
- 在 \(s\) 后添加字符串;
- 求 \(s\) 的所有非空回文子串数目。
任意时刻 \(|s|\le4\times10^5\),\(q\le10^5\)。
\(\mathcal{Solution}\)
双向 PAM 模板题。
思考一个正常的 PAM 所维护的——一个 DFA,每个结点的连边代表左右各加同一个字符;还有一个 fail 树,连向结点的最长回文后缀(当然也就是最长回文前缀)。在双向 PAM 也是一个道理,增量法构造过程中顺便处理 fail 树深度和即可。
复杂度 \(\mathcal O(|s|+q)\)。
\(\mathcal{Solution}\)
/*~Rainybunny~*/
#include <cstdio>
#include <cstring>
#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
typedef long long LL;
const int MAXN = 4e5, MAXL = 7e5;
char s[MAXL + 10];
int ptrf, ptrb;
struct PalindromeAutomaton {
int node, len[MAXN + 5], fail[MAXN + 5], ch[MAXN + 5][26];
int rlas, llas, dep[MAXN + 5];
PalindromeAutomaton() { node = rlas = llas = 1, len[1] = -1, fail[0] = 1; }
inline int pushF( char c ) {
s[--ptrf] = c, c -= 'a'; int p = llas;
for ( ; s[ptrf + len[p] + 1] != s[ptrf]; p = fail[p] );
if ( !ch[p][c] ) {
len[++node] = len[p] + 2; int q = fail[p];
for ( ; s[ptrf + len[q] + 1] != s[ptrf]; q = fail[q] );
dep[node] = dep[fail[node] = ch[q][c]] + 1, ch[p][c] = node;
}
llas = ch[p][c];
if ( len[llas] == ptrb - ptrf + 1 ) rlas = llas;
return dep[llas];
}
inline int pushB( char c ) {
s[++ptrb] = c, c -= 'a'; int p = rlas;
for ( ; s[ptrb - len[p] - 1] != s[ptrb]; p = fail[p] );
if ( !ch[p][c] ) {
len[++node] = len[p] + 2; int q = fail[p];
for ( ; s[ptrb - len[q] - 1] != s[ptrb]; q = fail[q] );
dep[node] = dep[fail[node] = ch[q][c]] + 1, ch[p][c] = node;
}
rlas = ch[p][c];
if ( len[rlas] == ptrb - ptrf + 1 ) llas = rlas;
return dep[rlas];
}
} pam;
int main() {
ptrf = ( ptrb = 3e5 ) + 1;
LL ans = 0;
for ( char c; 'a' <= ( c = getchar() ) && c <= 'z';
ans += pam.pushB( c ) );
int q, op; char tmp[1005];
for ( scanf( "%d", &q ); q--; ) {
scanf( "%d", &op );
if ( op == 1 ) {
scanf( "%s", tmp );
for ( int i = 0; tmp[i]; ans += pam.pushB( tmp[i++] ) );
} else if ( op == 2 ) {
scanf( "%s", tmp );
for ( int i = 0; tmp[i]; ans += pam.pushF( tmp[i++] ) );
} else {
printf( "%lld\n", ans );
}
}
return 0;
}
Solution -「LOJ #141」回文子串 ||「模板」双向 PAM的更多相关文章
- 图解最长回文子串「Manacher 算法」,基础思路感性上的解析
问题描述: 给你一个字符串 s,找到 s 中最长的回文子串. 链接:https://leetcode-cn.com/problems/longest-palindromic-substring 「Ma ...
- hdu 3068 最长回文 【Manacher求最长回文子串,模板题】
欢迎关注__Xiong的博客: http://blog.csdn.net/acmore_xiong?viewmode=list 最长回文 ...
- hdu 3068 最长回文子串 马拉车模板
前几天用后缀数组写过一次这题,毫无疑问很感人的TLE了-_-|| 今天偶然发现了马拉车模板,O(N)时间就搞定 reference:http://acm.uestc.edu.cn/bbs/read.p ...
- manacher求最长回文子串算法模板
#include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> ...
- 最长回文子串 —— Manacher (马拉车) 算法
最长回文子串 回文串就是原串和反转字符串相同的字符串.比如 aba,acca.前一个是奇数长度的回文串,后一个是偶数长度的回文串. 最长回文子串就是一个字符串的所有子串中,是回文串且长度最长的子串. ...
- Manacher (马拉车) 算法:解决最长回文子串的利器
最长回文子串 回文串就是原串和反转字符串相同的字符串.比如 aba,acca.前一个是奇数长度的回文串,后一个是偶数长度的回文串. 最长回文子串就是一个字符串的所有子串中,是回文串且长度最长的子串. ...
- LeetCode 5——最长回文子串
1. 题目 2. 解答 我们定义状态 state[i][j] 表示子串 s[i, j] 是否为回文子串,如果 s[i, j] 为回文子串,并且有 s[i-1] == s[j+1],那么 s[i-1, ...
- 每日一道 LeetCode (48):最长回文子串
每天 3 分钟,走上算法的逆袭之路. 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee ...
- LeetCode[5] 最长的回文子串
题目描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...
随机推荐
- js 关于 data.xuNum = xuNum++; 赋值写法 的探讨
1 .源码 let xuNum = 0; let data = []; data.xuNum = xuNum++; console.log(data.xuNum) 2.打印结果 // 0 3.原因 ...
- centos7 系统正则符号
点符号 . 匹配任意一个字符,且只有一个字符 星符号 * 匹配任意0和或多个以上连续的字符 扩展符号 括号符号[] 匹配括号出现的字符信息 [^abc] --表示排除含有abc字符的内容,是单个字符a ...
- Java定时调度
一.实现方式 Timer:单线程,串行: ScheduledExecutor:并行,论询,实现麻烦: Spring Scheduler:适合小任务: JcronTab:按照crontab语法编写的ja ...
- Flowable实战(一)启动第一个完整流程
一.前言: 发现网上关于Flowable的资料基本都是浅尝辄止,对如何构建一个企业级的流程应用说明很少,所以写个实战系列,希望对大家和自己,都有所帮助. 二.认识Flowable Flowab ...
- TestNG 运行Webdriver测试用例
1.单击选中的新建工程的名称,按Ctrl+N组合键,弹出对话框选择"TestNG"下的"TestNG class"选项,点击"next" 2 ...
- 【Java】单例设计模式
文章目录 单例设计模式 什么是设计模式 单例设计模式 实现 饿汉式 懒汉式 饿汉式与懒汉式的区别 饿汉式 懒汉式 单例模式的应用场景 单例设计模式 什么是设计模式 设计模式是在大量的实践中总结和理论化 ...
- Rancher Fleet使用教程
官方文档: https://fleet.rancher.io/ https://github.com/rancher/fleet 博客截止日期为:20201204 当前官网版本为v0.3.0,但在实践 ...
- Java基础-JNI入门示例
1.JNI是什么? JNI(Java Native Interface) Java本地接口,又叫Java原生接口.它允许Java调用C/C++的代码,同时也允许在C/C++中调用Java的代码. 可以 ...
- 2022GDUT寒假专题学习-1 B,F,I,J题
专题链接:专题学习1 - Virtual Judge (vjudge.net) B - 全排列 题目 思想 这道题可以用DFS进行求解,但是一看到全排列,其实可以立刻想到一个STL函数:next_pe ...
- 解决vscode下载很慢的问题
1.打开vscode官网,https://code.visualstudio.com; 2.点击下载稳定版;这里我的电脑是win10版本 3.下载时可以去谷歌的下载内容里面,看到正在下载的vscode ...