\(\mathcal{Description}\)

  Link.

  给定字符串 \(s\),处理 \(q\) 次操作:

  1. 在 \(s\) 前添加字符串;
  2. 在 \(s\) 后添加字符串;
  3. 求 \(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的更多相关文章

  1. 图解最长回文子串「Manacher 算法」,基础思路感性上的解析

    问题描述: 给你一个字符串 s,找到 s 中最长的回文子串. 链接:https://leetcode-cn.com/problems/longest-palindromic-substring 「Ma ...

  2. hdu 3068 最长回文 【Manacher求最长回文子串,模板题】

    欢迎关注__Xiong的博客: http://blog.csdn.net/acmore_xiong?viewmode=list 最长回文                                 ...

  3. hdu 3068 最长回文子串 马拉车模板

    前几天用后缀数组写过一次这题,毫无疑问很感人的TLE了-_-|| 今天偶然发现了马拉车模板,O(N)时间就搞定 reference:http://acm.uestc.edu.cn/bbs/read.p ...

  4. manacher求最长回文子串算法模板

    #include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> ...

  5. 最长回文子串 —— Manacher (马拉车) 算法

    最长回文子串 回文串就是原串和反转字符串相同的字符串.比如 aba,acca.前一个是奇数长度的回文串,后一个是偶数长度的回文串. 最长回文子串就是一个字符串的所有子串中,是回文串且长度最长的子串. ...

  6. Manacher (马拉车) 算法:解决最长回文子串的利器

    最长回文子串 回文串就是原串和反转字符串相同的字符串.比如 aba,acca.前一个是奇数长度的回文串,后一个是偶数长度的回文串. 最长回文子串就是一个字符串的所有子串中,是回文串且长度最长的子串. ...

  7. LeetCode 5——最长回文子串

    1. 题目 2. 解答 我们定义状态 state[i][j] 表示子串 s[i, j] 是否为回文子串,如果 s[i, j] 为回文子串,并且有 s[i-1] == s[j+1],那么 s[i-1, ...

  8. 每日一道 LeetCode (48):最长回文子串

    每天 3 分钟,走上算法的逆袭之路. 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee ...

  9. LeetCode[5] 最长的回文子串

    题目描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...

随机推荐

  1. Oracle 报 ORA-00054资源正忙的解决办法

    oracle之报错:ORA-00054: 资源正忙,要求指定 NOWAIT 问题如下: SQL> conn scott/tiger@vm_database Connected to Oracle ...

  2. HBase文档学习顺序

    1.<HBase基础概念知识学习> https://www.toutiao.com/i6774215329498268164/ 2.<VM安装CentOS6.5> https: ...

  3. layui 时间插件,change&&done,按照官网写法无效,解决方式!

    摘抄自 hahei2020:https://blog.csdn.net/hahei2020/article/details/79285370 layui 时间插件, 当选择时间或时间发生改变后,按照官 ...

  4. 用jquery实现省市联动

    <!-- 需求: [1] 动态生成省份选择框. [2] 当选择了省份的某一项时, 动态改变 城市选择中的列表项. --> <!DOCTYPE html> <html la ...

  5. Windows 重装系统,配置 WSL,美化终端,部署 WebDAV 服务器,并备份系统分区

    最新博客文章链接 最近发现我 Windows11 上的 WSL 打不开了,一直提示我虚拟化功能没有打开,但我看了下配置,发现虚拟化功能其实是开着的.然后试了各种方法,重装了好几次系统,我一个软件一个软 ...

  6. 推荐一个最懂程序员的google插件

    0.前言 很多人应该也和我一样,使用google浏览器时,它的主页是真不咋地,太单调了,用起来贼不爽,想整它很久了 一打开就是上面的样子,让我看起来真心真心不爽 当然:为了这个不关技术的瞎犊子事情,曾 ...

  7. 基于华为云服务器的FTP站点搭建

    前言 主要介绍了华为云上如何使用弹性云服务器的Linux实例使用vsftpd软件搭建FTP站点.vsftpd全称是"very secure FTP daemon",是一款在Linu ...

  8. PWA 技术落地!让你的站点(Web)秒变APP(应用程序)

    Web应用方兴未艾,我们已经十分习惯习惯了在电脑上进行以自己的工作,而随着众多功能强大的在线网站,我们的Windows的桌面也不再拥挤着各种快捷方式:不光是PC端,在移动端我们也不再在浩如烟海的应用市 ...

  9. 推荐召回--基于物品的协同过滤:ItemCF

    目录 1. 前言 2. 原理&计算&改进 3. 总结 1. 前言 说完基于用户的协同过滤后,趁热打铁,我们来说说基于物品的协同过滤:"看了又看","买了又 ...

  10. Gradle下载安装教程

    前言 1.gradle和maven一样都是用来构建java程序的,maven2004年开始兴起,gradle2012年开始诞生,既然已经有了maven这么成熟的构建工具为什么还有gradle的诞生呢, ...