回文自动机(BZOJ2565)
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std; int p,next[][],cnt[],len[],fail[],last,a[],maxl[],maxr[];
char st[]; int newnode(int l){
p++;
for (int i=;i<=;i++) next[p][i]=;
cnt[p]=;
len[p]=l;
return(p);
} void init(){
p=-;
newnode();
newnode(-);
last=;
st[]=-;
fail[]=;
} int get_fail(int po,int x,int num){
while (a[po-len[x]-]!=num) x=fail[x];
return(x);
} void add(int po,int c){
int cur=get_fail(po,last,c);
if (!next[cur][c]){
int now=newnode(len[cur]+);
fail[now]=next[get_fail(po,fail[cur],c)][c];
next[cur][c]=now;
}
last=next[cur][c];
cnt[last]++;
} void count(){
for (int i=p;i>=;i--) cnt[fail[i]]+=cnt[i];
} int main(){
scanf("%s",&st);
int n=strlen(st);
for (int i=;i<=n;i++) a[i]=st[i-]-'a'+; init();
for (int i=;i<=n;i++)
add(i,a[i]),maxl[i]=len[last];
count(); for (int i=;i<=n/;i++){
int t=a[i];a[i]=a[n-i+];a[n-i+]=t;
}
init();
for (int i=;i<=n;i++)
add(i,a[i]),maxr[n-i+]=len[last];
count(); int ans=;
for (int i=;i<n;i++) ans=max(ans,maxl[i]+maxr[i+]);
printf("%d\n",ans);
}
每个节点表示一个本质不同的回文串(最多n个)。
进行count()后,cnt中存每个本质不同的回文串的出现次数。
------------------------------------------------------------------------
CODECHEF APRIL LUNCHTIME 2015 PALPROB
在fail树上转移palindromness
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#define LL long long
using namespace std; map <int,int> mp,mpb;
int p,tr[][],cnt[],len[],fail[],last,a[],maxl[],maxr[];
int ans[],nd[],nxt[],des[],T,scnt;
char st[]; void addedge(int x,int y){
nxt[++scnt]=nd[x];des[scnt]=y;nd[x]=scnt;
} int newnode(int l){
p++;
for (int i=;i<=;i++) tr[p][i]=;
cnt[p]=;ans[p]=;
len[p]=l;
return(p);
} void init(){
p=-;
newnode();newnode(-);
last=;
st[]=-;
fail[]=;
} int get_fail(int po,int x,int num){
while (a[po-len[x]-]!=num) x=fail[x];
return(x);
} void add(int po,int c){
int cur=get_fail(po,last,c);
if (tr[cur][c]==){
int now=newnode(len[cur]+);
fail[now]=tr[get_fail(po,fail[cur],c)][c];
tr[cur][c]=now;
}
last=tr[cur][c];
cnt[last]++;
} void count(){
for (int i=p;i>=;i--) cnt[fail[i]]+=cnt[i];
} void dfs(int po){
if (len[po]>=){
int t;
if (len[po]<=) t=-;else t=len[po]/;
int p=mp[t];
if (mpb[t])
ans[po]=ans[p]+;else
ans[po]=;
} mpb[len[po]]=;mp[len[po]]=po;
for (int p=nd[po];p!=-;p=nxt[p])
dfs(des[p]);
mpb[len[po]]=;
} int main(){
freopen("a.in","r",stdin); scanf("%d",&T);
while (T--){
scanf("%s",&st);
int n=strlen(st);
for (int i=;i<=n;i++) a[i]=st[i-]-'a'+; init();
for (int i=;i<=n;i++)
add(i,a[i]);
count(); for (int i=;i<=p;i++) nd[i]=-;scnt=;
for (int i=;i<=p;i++) if (i!=) addedge(fail[i],i); mp.clear();mpb.clear();
dfs(); LL ret=;
for (int i=;i<=p;i++) ret+=(LL)ans[i]*cnt[i];
printf("%lld\n",ret);
}
}
回文自动机(BZOJ2565)的更多相关文章
- bzoj千题计划305:bzoj2565: 最长双回文串(回文自动机)
https://www.lydsy.com/JudgeOnline/problem.php?id=2565 正着构造回文自动机 倒过来再构造一个回文自动机 分别求出以位置i开始的和结尾的最长回文串 # ...
- 后缀自动机/回文自动机/AC自动机/序列自动机----各种自动机(自冻鸡) 题目泛做
题目1 BZOJ 3676 APIO2014 回文串 算法讨论: cnt表示回文自动机上每个结点回文串出现的次数.这是回文自动机的定义考查题. #include <cstdlib> #in ...
- URAL 2040 (回文自动机)
Problem Palindromes and Super Abilities 2 (URAL2040) 题目大意 给一个字符串,从左到右依次添加,询问每添加一个字符,新增加的回文串数量. 解题分析 ...
- URAL 2040 Palindromes and Super Abilities 2 (回文自动机)
Palindromes and Super Abilities 2 题目链接: http://acm.hust.edu.cn/vjudge/contest/126823#problem/E Descr ...
- [模板] 回文树/回文自动机 && BZOJ3676:[Apio2014]回文串
回文树/回文自动机 放链接: 回文树或者回文自动机,及相关例题 - F.W.Nietzsche - 博客园 状态数的线性证明 并没有看懂上面的证明,所以自己脑补了一个... 引理: 每一个回文串都是字 ...
- BZOJ2160拉拉队排练——回文自动机
题目描述 艾利斯顿商学院篮球队要参加一年一度的市篮球比赛了.拉拉队是篮球比赛的一个看点,好的拉拉队往往能帮助球队增加士气,赢得最终的比赛.所以作为拉拉队队长的楚雨荨同学知道,帮助篮球队训练好拉拉队有多 ...
- BZOJ2084[Poi2010]Antisymmetry——回文自动机
题目描述 对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一样,就称作“反对称”字符串.比如00001111和010101就是反对称的,1001就不是.现在给出一个长度为N的0 ...
- BZOJ2342[Shoi2011]双倍回文——回文自动机
题目描述 输入 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. 输出 输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文 ...
- 【XSY2715】回文串 树链剖分 回文自动机
题目描述 有一个字符串\(s\),长度为\(n\).有\(m\)个操作: \(addl ~c\):在\(s\)左边加上一个字符\(c\) \(addr~c\):在\(s\)右边加上一个字符 \(tra ...
- 字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)
模板 后缀数组 #include<bits/stdc++.h> #define R register int using namespace std; const int N=1e6+9; ...
随机推荐
- H5中的touch事件
touch中共有touchstart.touchmove和touchend三个事件: touchstart:触摸开始的时候触发 touchmove:手指在屏幕上滑动的时候触发 touchend:触摸结 ...
- 免费薪资总额管控系统-JXHR2016
•工资总额是指按照国家统计局规定的统计口径或企业规定,在一定时期内支付给各类用工的劳动报酬总额 •工资总额,即基本工资,包括岗位工资.各项津补贴 •JXHR2016以薪酬管控为核心,结合人力资源规划. ...
- IOS客户端实现RSA加密
在IOS的app登陆模块,用户名和密码如果直接传给后台服务器,很容易被截获并伪造网络请求, 如果利用RSA算法在每个客户端利用公钥解密,服务器端进行私钥解密,即使截获了密码也是无法解密的 在这里只介绍 ...
- 简单的学习心得:网易云课堂Android开发第三章自定义控件
这一章分三部分: (1)自定义控件:老师先简单讲解了一些细节,如为什么不用px,而要用dp,只因机型的屏幕分辨率不同,用px会导致差异太大.然后演示了制作自定义控件的步骤,先在xml文件中添加对应的自 ...
- Objective-C 快速入门--基础(四)
1.什么是Block? ① 块语法,本质上是匿名函数(没有名称的函数): ② Block是OC中的一种数据类型,在iOS开发中被广泛使用: ③ ^是Block的特有标记: ④ Block的实现代码包含 ...
- android 双缓存机制
废话不多说,直接贴代码! 所谓的双缓存,第一就是缓存在内存里面,第二就是缓存在SD卡里面,当你需要加载数据时,先去内存缓存中查找,如果没有再去SD卡中查找,并且用户可以自选使用哪种缓存! 缓存内存和缓 ...
- Android编码规范03
一.整个项目的目录规范化sundy老师建议有:系统目录规范.源代码目录规范. 1.系统目录规范: 指项目目录中不仅包括源代码,还需要包括:需求相关文档.设计文档.计划日志文档.测试文档.项目进行中学习 ...
- Android应用开发基础之十二:版本控制
为什么需要版本控制? 场景1: 你的代码正常工作 你改了其中的几行代码 程序出了问题 你把代码改回来 程序还是不能正常工作——为什么? 场景2: 你的程序昨天还能正常运行 昨天晚上你修改了很多内容,做 ...
- Redhat Linux安装JDK 1.7
本篇主要介绍在Redhat Linux(Red Hat Enterprise Linux Server release 5.7 (Tikanga))系统上安装JDK 1.7,其它Linux平台安装也大 ...
- TCP三次握手建立连接
基本过程: ISN(初始序号)随时间变化,每一个连接具有不同的ISN,防止在网络延迟中分组被重新发送. 请求端发送SYN(同步序号 )=1,seq=ISN(32bits序号,每4ms+ ...