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 ...
随机推荐
- Spring IOC(通过实例介绍,属性与构造方法注入)
概括说明:下面通过实例介绍下属性方法注入.构造方法注入 1.源码结构图 2.代码介绍 (1).Dao接口 :UserDAO (2).Dao接口实现:UserDAOImpl (3).实体类:User ( ...
- PHP邮箱的正则表达式
邮箱的正则:/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i
- ASP.NET中指定自定义HTTP响应标头
新建一个类HideServerHeaderHelper,继承 IHttpModule,然后重写 OnPreSendRequestHeaders,Dispose,Init方法,如下代码所示 using ...
- Lifting the Stone(多边形重心)
Lifting the Stone Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- 【HTML5开发系列】DOM及其相关
对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口.DOM把Javascript和HTML文档的结构和内容连接起来,通过DOM可以控 ...
- Python菜鸟之路:Python基础-逼格提升利器:装饰器Decorator
一.装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等. 装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身 ...
- SQLServer判断一个IP是否在一个IP段里
declare @ip1 varchar(20)declare @ip2 varchar(20)set @ip1='221.231.138.101'set @ip2='255.255.255.255' ...
- Dajngo admin使用
Dajngo admin使用 Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.你可以在项目的 settings.py 中的 INS ...
- ThoughtWorks(中国) 程序员读书雷达
ThoughtWorks(中国)程序员读书雷达 软件业的特点是变化.若要提高软件开发的技能,就必须跟上技术发展的步伐.埋首醉心于项目开发与实战,固然能够锤炼自己的开发技巧,却难免受限于经验与学识.世界 ...
- Swift学习 --- 2.1基础部分
1.swift 能够省去; 2.println与print的差别就是一个能够换行一个不能够 3.swift省去了.h与.m 直接一个swift文件 4.元组能够返回多个值,元组(tuples)把多个值 ...