\(\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. nvm安装vue-cli

    使用nvm可以更换nodejs版本.方便不同项目的切换 1.安装nvm(本人提供版本为1.1.9,当前最新) ① 到官网自行下载 https://github.com/coreybutler/nvm- ...

  2. 编写程序向HBase添加日志信息

    关注公众号:分享电脑学习回复"百度云盘" 可以免费获取所有学习文档的代码(不定期更新) 承接上一篇文档<日志信息和浏览器信息获取及数据过滤> 上一个文档最好做个本地测试 ...

  3. JavaWeb中Cookie会话管理,理解Http无状态处理机制

    注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6512995108961387015/ 1.<Servlet简单实现开发部署过程> 2.<Serv ...

  4. uni-app开发的h5,使用微信授权登录(前置条件+具体代码)

    原文 微信内嵌浏览器运行H5版时,可以调起微信登录 普通浏览器调起微信登陆是不开放的,只有个别开发者才有,比如京东 前置条件 在微信内嵌浏览器运行H5版时,调起微信登录,需要配置回调域名 (请注意,这 ...

  5. iOS二进制方案真实落地经验(30分钟降低到10分钟以内)

    iOS二进制方案真实落地经验(30分钟降低到10分钟以内) 我们做iOS二进制化断断续续尝试了一年多了,来来回回换了三个架构师去尝试落地,今日完全落地,在此做个总结 背景 工程基于cocoapod的组 ...

  6. HDUA/B

    同样求逆元的题目,费马的条件,首先要保证p为质数,然后保证a与p互素. 数据范围问题,要保证在数据范围内,所以要b先模上mod #include<bits/stdc++.h> using ...

  7. Vue3项目的简单搭建与项目结构的简单介绍

    Vue3项目的创建与运行 本文记录下自己近期学习的Vue3项目的创建,以及如何去运行一个Vue应用,同时包括对Vue项目结构进行一个简单的介绍. 一.node与npm的安装 通常平常进行开发的同学应该 ...

  8. winform 中心旋转 图片旋转

    //设置左上角到中心点 g.TranslateTransform(int.Parse(x), int.Parse(y)); //旋转角度 g.RotateTransform(int.Parse(&qu ...

  9. HBase结构

      Pig,可以使用Pig Latin流式编程语言来操作HBase中的数据 Hive,可以使用类似SQL语言来访问HBase,最终本质是编译成MapReduce Job来处理HBase表数据,适合做数 ...

  10. JVM调优方法

    目 录 目 录 I 诠释JVM调优 1 第1章 JVM内存模型及垃圾收集算法 1 1.1 根据Java虚拟机规范,JVM将内存划分为 1 1.2 垃圾回收算法 1 第2章 内存泄漏及解决方法 2 2. ...