bzoj 2342: 双倍回文 回文自动机
题目大意:
定义双倍回文串的左一半和右一半均是回文串的长度为4的倍数的回文串
求一个给定字符串中最长的双倍回文串的长度
题解:
- 我们知道可以简单地判定以某一点结尾的最长回文串
- 我们知道可以简单地判定以某一点开头的最长回文串
啥?第二个?你把串倒过来不就行了?
所以我们枚举双倍回文串的断点再判定即可.
我们发现我们每次都要取枚举到的两个端点的最长的相同偶数长度的回文串
并且这两个回文串还要相同。。也就是说在回文自动机上这是同一个点
所以我们在fail树上求lca即可
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = 1000010;
struct Edge{
int to,next;
}G[maxn];
int head[maxn],cnt;
void add(int u,int v){
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
}
#define v G[i].to
int son[maxn],top[maxn],siz[maxn],dep[maxn],fa[maxn];
void dfs(int u){
siz[u] = 1;
for(int i = head[u];i;i=G[i].next){
if(v == fa[u]) continue;
fa[v] = u;
dep[v] = dep[u] + 1;
dfs(v);
siz[u] += siz[v];
if(son[u] == -1 || siz[son[u]] < siz[v]) son[u] = v;
}
}
void dfs(int u,int tp){
top[u] = tp;
if(son[u] != -1) dfs(son[u],tp);
for(int i = head[u];i;i=G[i].next){
if(v == son[u] || v == fa[u]) continue;
dfs(v,v);
}
}
#undef v
inline int lca(int u,int v){
while(top[u] != top[v]){
if(dep[top[u]] < dep[top[v]]) swap(u,v);
u = fa[top[u]];
}return dep[u] < dep[v] ? u : v;
}
struct Node{
map<int,int>nx;
int fail,len;
}T[maxn];
int mp[maxn],last,nodecnt,len,str[maxn];
int f[maxn];
inline void init(){
T[last = nodecnt = 0].fail = 1;
T[++nodecnt].len = -1;
str[len=0] = -1;add(1,0);
f[0] = f[1] = -1;
}
char s[maxn];
inline void insert(int i){
int c = s[i] - 'a',cur,p,x;str[++len] = c;
for(p = last;str[len-T[p].len-1] != str[len];p = T[p].fail);
if(T[p].nx[c] == 0){
T[cur = ++ nodecnt].len = T[p].len + 2;
for(x = T[p].fail;str[len-T[x].len-1] != str[len];x = T[x].fail);
T[cur].fail = T[x].nx[c];T[p].nx[c] = cur;
f[cur] = f[T[cur].fail];
if(T[cur].len % 2 == 0) f[cur] = cur;
add(T[cur].fail,cur);
}mp[i] = last = T[p].nx[c];
}
int main(){init();
memset(fa,-1,sizeof fa);
memset(son,-1,sizeof son);
int n;read(n);scanf("%s",s);
s[n] = 'z' + 1;s[n+1] = 'z' + 2;
for(int i=0;i<n;++i){
s[(n+1)+(n-i)] = s[i];
}
int len = (n << 1) + 2;
for(int i=0;i<len;++i) insert(i);
dfs(1);dfs(1,1);int ans = 0;
for(int i=0;i<n-1;++i){
int x = lca(mp[i],mp[(n+1)+(n-i-1)]);
if(f[x] != -1) ans = max(ans,T[f[x]].len<<1);
}printf("%d\n",ans);
getchar();getchar();
return 0;
}
bzoj 2342: 双倍回文 回文自动机的更多相关文章
- BZOJ 2342 双倍回文(manacher算法)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2342 题意:定义双倍回文串为:串的长度为4的倍数且串的前一半.后一半.串本身均是回文的. ...
- [BZOJ 2342] 双倍回文
Link:https://www.lydsy.com/JudgeOnline/problem.php?id=2342 Algorithm: 解决回文串问题,一般从对称轴下手. 肯定先跑一边Manach ...
- Vue 2.5 发布了:15篇前端热文回看
Vue 2.5 发布了:15篇前端热文回看 2017-11-02 前端大全 (点击上方公众号,可快速关注) 本文精选了「前端大全」2017 年 10 月的 15 篇热门文章.其中有职场分享.技术分享和 ...
- 6 大主流 Web 框架优缺点对比:15篇前端热文回看
摘自:http://blog.csdn.net/VhWfR2u02Q/article/details/78993079 注:以下文章,点击标题即可阅读 <6 大主流 Web 框架优缺点对比> ...
- [BZOJ 3530] [Sdoi2014] 数数 【AC自动机+DP】
题目链接:BZOJ - 3530 题目分析 明显是 AC自动机+DP,外加数位统计. WZY 神犇出的良心省选题,然而去年我太弱..比现在还要弱得多.. 其实现在做这道题,我自己也没想出完整解法.. ...
- BZOJ 2342 [SHOI2011]双倍回文 (回文自动机)
题目大意:略 先建出$PAM$ 因为双倍回文串一定是4的倍数,所以找出$PAM$里所有$dep$能整除4的节点 看这个串是否存在一个回文后缀,长度恰好为它的一半,沿着$pre$链往上跳就行了 暴跳可能 ...
- 2018.06.30 BZOJ 2342: [Shoi2011]双倍回文(manacher)
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符串 ...
- BZOJ 2342: [Shoi2011]双倍回文 马拉车算法/并查集
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1123 Solved: 408 题目连接 http://w ...
- BZOJ 2342: 【SHOI2011】 双倍回文
题目链接:双倍回文 回文自动机第二题.构出回文自动机,那么一个回文串是一个“双倍回文”,当且仅当代表这个串的节点\(u\)顺着\(fail\)指针往上跳,可以找到一个节点\(x\)满足\(2len_x ...
随机推荐
- Linux环境下,使用PHP创建一个守护进程
<?php $pid = pcntl_fork(); // fork if ($pid < 0) exit; else if ($pid) // parent exit; else { / ...
- NSNotificationCenter详解
本文转载至 http://blog.csdn.net/chengyingzhilian/article/details/7874408 作用:NSNotificationCenter是专门供程序中不同 ...
- Pycharm 中错误ImportError: No module named appium
Q: Pycharm 中错误ImportError: No module named appium A: Pycharm IDE Preferences -> Project Interpret ...
- VS2010 fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
VS2010在经历一些更新后,建立Win32 Console Project时会出“error LNK1123” 错误,解决方案为将 项目|项目属性|配置属性|清单工具|输入和输出|嵌入清单 “是”改 ...
- 我为什么选择采用node.js来做新一代的EasyDarwin RTSP开源流媒体服务器
在去年我们还未开始开发基于node.js的新版本EasyDarwin RTSP开源流媒体服务器的时候,我写了一篇博客<对EasyDarwin开源项目后续发展的思考:站在巨人的肩膀上再跳上另一个更 ...
- iOS 字符串截取,将字符串中用括号包含的内容去除
//去除字符串中用括号括住的位置 -(NSString *)handleStringWithString:(NSString *)str{ NSMutableString * muStr = [NSM ...
- Python过滤
text = "A2A"s = filter(lambda ch: ch in '0123456789', text)print int(s)
- mysql设置有外键的主键自增及其他
有外键的主键设置自增. ; ALTER TABLE `<table>` MODIFY COLUMN `id` ) NOT NULL AUTO_INCREMENT FIRST; 创建数据库, ...
- 简单做出HTML5翻页效果文字特效
之前在网上看到一款比较有新意的HTML5文字特效,文字效果是当鼠标滑过是出现翻开折叠的效果,类似书本翻页.于是我兴致勃勃的点开源码看了一下,发现其实实现也挺简单的,主要利用了CSS3的transfor ...
- [原创]java WEB学习笔记23:MVC案例完整实践(part 4)---模糊查询的设计与实现
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...