模板

后缀数组

#include<bits/stdc++.h>
#define R register int
using namespace std;
const int N=1e6+9;
int sa[N],rk[N],hei[N],x[N],y[N],c[N];
char s[N];
void Rsort(R n,R m){
for(R i=1;i<=n;++i)++c[x[i]];
for(R i=2;i<=m;++i)c[i]+=c[i-1];
for(R i=n;i;--i)sa[c[x[y[i]]]--]=y[i];
}
int main(){
R n=fread(s+1,1,N,stdin)-1,m=122;
for(R i=1;i<=n;++i)x[i]=s[i],y[i]=i;
Rsort(n,m);
for(R k=1,p=0;k<=n;k<<=1,p=0){
for(R i=n-k+1;i<=n;++i)y[++p]=i;
for(R i=1;i<=n;++i)if(sa[i]>k)y[++p]=sa[i]-k;
memset(c+1,0,4*m);Rsort(n,m);memcpy(y+1,x+1,4*n);
x[sa[1]]=p=1;
for(R i=2;i<=n;++i)
x[sa[i]]=p+=y[sa[i]]!=y[sa[i-1]]||y[sa[i]+k]!=y[sa[i-1]+k];
if((m=p)==n)break;
}
for(R i=1;i<=n;++i)rk[sa[i]]=i;
for(R i=1,p=0;i<=n;++i){
for(p-=(bool)p;s[i+p]==s[sa[rk[i]-1]+p];++p);
hei[rk[i]]=p;
}
for(R i=1;i<=n;++i)printf("%d ",sa[i]);puts("");
for(R i=1;i<=n;++i)printf("%d ",rk[i]);puts("");
for(R i=1;i<=n;++i)printf("%d ",hei[i]);puts("");
return 0;
}

后缀自动机

hiho1445 后缀自动机二·重复旋律5

#include<bits/stdc++.h>
#define RG register
#define R RG int
using namespace std;
const int N=2e6+9;
int lst=1,nod=1,ch[N][26],fa[N],len[N];
char s[N];
void Extend(R c){
R f=lst,p=lst=++nod;
len[p]=len[f]+1;
while(f&&!ch[f][c])ch[f][c]=p,f=fa[f];
if(!f){fa[p]=1;return;}
R x=ch[f][c];
if(len[x]==len[f]+1){fa[p]=x;return;}
R y=++nod;memcpy(ch[y],ch[x],104);
len[y]=len[f]+1;fa[y]=fa[x];fa[x]=fa[p]=y;
while(f&&ch[f][c]==x)ch[f][c]=y,f=fa[f];
}
int main(){
for(char c=getchar();c>='a';c=getchar())Extend(c-'a');
long long ans=0;
for(R i=1;i<=nod;++i)ans+=len[i]-len[fa[i]];
cout<<ans<<endl;
return 0;
}

广义后缀自动机

注意两个特判

第一个特判是因为已经有这个状态了

第二个特判是因为分裂出y后,p失去意义了

大多数时候,模式串是独立的,可以每次把lst重赋值为1

如果模式串是Trie的话,DFS建SAM会被卡成\(O(叶节点个数×|S|)\)

正确写法是在BFS遍历Trie时进行Extend,详情参考XZY巨佬的总结

洛谷P3346 [ZJOI2015]诸神眷顾的幻想乡

#include<bits/stdc++.h>
#define LL long long
#define RG register
#define R RG int
#define G if(++ip==ie)if(fread(ip=buf,1,SZ,stdin))
using namespace std;
const int SZ=1<<19,N=2e5+9,M=10*N;
char buf[SZ],*ie=buf+SZ,*ip=ie-1;
inline int in(){
G;while(*ip<'-')G;
R x=*ip&15;G;
while(*ip>'-'){x*=10;x+=*ip&15;G;}
return x;
}
int he[N],ne[N],to[N];
char s[N];
namespace GSAM{
int nod=1,ch[2*M][10],fa[2*M],len[2*M];
int Extend(R f,R c){
if(len[ch[f][c]]==len[f]+1)return ch[f][c];
R p=++nod;
len[p]=len[f]+1;
while(f&&!ch[f][c])ch[f][c]=p,f=fa[f];
if(!f)return fa[p]=1,p;
R x=ch[f][c];
if(len[x]==len[f]+1)return fa[p]=x,p;
R y=++nod,lst=len[p]==len[f]+1?y:p;
memcpy(ch[y],ch[x],sizeof(ch[y]));
len[y]=len[f]+1;fa[y]=fa[x];fa[x]=fa[p]=y;
while(f&&ch[f][c]==x)ch[f][c]=y,f=fa[f];
return lst;
}
LL calc(){
LL ans=0;
for(R i=1;i<=nod;++i)ans+=len[i]-len[fa[i]];
return ans;
}
}
namespace Trie{
int p,ch[M][10],lst[M],q[M];
void dfs(R&u,R x,R f){
if(!u)u=++p;
for(R i=he[x];i;i=ne[i])
if(to[i]!=f)dfs(ch[u][s[to[i]]],to[i],x);
}
void bfs(){
lst[0]=1;
for(R h=0,t=0;h<=t;++h)
for(R x=q[h],y,i=0;i<10;++i)
if((y=ch[x][i]))lst[q[++t]=y]=GSAM::Extend(lst[x],i);
}
}
int main(){
R n=in(),m=in();
for(R i=1;i<=n;++i)s[i]=in();
for(R i=1,p=0;i<n;++i){
R x=in(),y=in();
ne[++p]=he[x];to[he[x]=p]=y;
ne[++p]=he[y];to[he[y]=p]=x;
}
for(R i=1;i<=n;++i)
if(!ne[he[i]])Trie::dfs(Trie::ch[0][s[i]],i,0);
Trie::bfs();
printf("%lld\n",GSAM::calc());
return 0;
}

后缀平衡树

不会

回文自动机

会板子了qaq

洛谷日报——强势图解回文自动机

洛谷P3649 [APIO2014]回文串

#include<bits/stdc++.h>
#define LL long long
#define R register int
using namespace std;
const int N=3e5+9;
char s[N];
int lst,nod=1,f[N],ch[N][26],len[N],sum[N];
inline void Extend(R i,R c){
R p=lst;
while(s[i-len[p]-1]!=s[i])p=f[p];
if(!ch[p][c]){
R q=f[p];
while(s[i-len[q]-1]!=s[i])q=f[q];
f[++nod]=ch[q][c];//注意先求fail再给ch赋值
len[ch[p][c]=nod]=len[p]+2;
}
++sum[lst=ch[p][c]];
}
int main(){
len[f[0]=f[1]=1]=-1;
cin>>(s+1);
R n=strlen(s+1);LL ans=0;
for(R i=1;i<=n;++i)Extend(i,s[i]-'a');
for(R x=nod;x;--x){//PAM建出来自带拓扑序直接for
ans=max(ans,(LL)sum[x]*len[x]);
sum[f[x]]+=sum[x];
}
cout<<ans<<endl;
return 0;
}

题单

hihocoder 重复旋律系列

【Done】重复旋律1(一个串的最长k重可重叠子串)

【Todo】重复旋律2(一个串的最长多重不可重叠子串)

【Done】重复旋律3(两个串的最长公共子串)

【Done】重复旋律4(一个串的周期重复次数最多的子串)

【Done】SAM基本概念

【Done】重复旋律5(一个串的本质不同子串个数)

【Done】重复旋律6(一个串的最长k重可重叠子串(对所有的k求答案))

【Todo】重复旋律7(一个数字串的本质不同子串的数值和)

【Todo】重复旋律8(一个文本串中与某模式串循环同构的子串计数)

【Todo】重复旋律9(字符串上的博弈)

自己发现or分享的一些好题

【Done】洛谷CF666E Forensic Examination

【Todo】洛谷CF700E Cool Slogans

【Todo】HDU5343 MZL's Circle Zhou(vjudge)

【Todo】HDU4622 Reincarnation(vjudge)(可做\(n,q\le10^5\))


【Todo】BZOJ3682 Phorni

【Todo】BZOJ2555 SubString

其他大佬的题单

https://www.cnblogs.com/Macaulish/p/4296557.html

https://www.cnblogs.com/mangoyang/p/9760416.html

https://blog.csdn.net/qq_39898877/article/details/82729385

https://www.cnblogs.com/xzyxzy/p/9186759.html

字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)的更多相关文章

  1. hdu多校第二场1009 (hdu6599) I Love Palindrome String 回文自动机/字符串hash

    题意: 找出这样的回文子串的个数:它本身是一个回文串,它的前一半也是一个回文串 输出格式要求输出l个数字,分别代表长度为1~l的这样的回文串的个数 题解: (回文自动机和回文树是一个东西) 首先用回文 ...

  2. 【BZOJ-4556】字符串 后缀数组+二分+主席树 / 后缀自动机+线段树合并+二分

    4556: [Tjoi2016&Heoi2016]字符串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 657  Solved: 274[Su ...

  3. 后缀自动机/回文自动机/AC自动机/序列自动机----各种自动机(自冻鸡) 题目泛做

    题目1 BZOJ 3676 APIO2014 回文串 算法讨论: cnt表示回文自动机上每个结点回文串出现的次数.这是回文自动机的定义考查题. #include <cstdlib> #in ...

  4. 牛客多校第四场 I string 后缀自动机/回文自动机

    这个回文自动机的板有问题,它虽然能过这道题,但是在计算size的时候会出锅! 题意: 求一个字符串中本质不同的连续子串有几个,但是某串和它反转后的字符串算一个. 题解: 要注意的是,一般字符串题中的“ ...

  5. Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解

    Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全   Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...

  6. [模板] 回文树/回文自动机 && BZOJ3676:[Apio2014]回文串

    回文树/回文自动机 放链接: 回文树或者回文自动机,及相关例题 - F.W.Nietzsche - 博客园 状态数的线性证明 并没有看懂上面的证明,所以自己脑补了一个... 引理: 每一个回文串都是字 ...

  7. bzoj千题计划306:bzoj2342: [Shoi2011]双倍回文 (回文自动机)

    https://www.lydsy.com/JudgeOnline/problem.php?id=2342 解法一: 对原串构建回文自动机 抽离fail树,从根开始dfs 设len[x]表示节点x表示 ...

  8. 2019 Multi-University Training Contest 2 I.I Love Palindrome String(回文自动机+字符串hash)

    Problem Description You are given a string S=s1s2..s|S| containing only lowercase English letters. F ...

  9. 洛谷P5496 回文自动机【PAM】模板

    回文自动机模板 1.一个串的本质不同的回文串数量是\(O(n)\)级别的 2.回文自动机的状态数不超过串长,且状态数等于本质不同的回文串数量,除了奇偶两个根节点 3.如何统计所有回文串的数量,类似后缀 ...

随机推荐

  1. Linq sum()时遇到NULL

    当使用linq求和sum()时,如果某列数据为null,就会出现异常 使用下面的语句即可解决相关问题: db.TableModel.Where(w => w.ID == ID).Select(s ...

  2. Python集合及其运算

    目录 集合(set) 集合的创建 集合的操作 集合的运算 子集与父集 集合(set) 集合是由不同可hash的值组成的,里面所有的值都是唯一的,也是无序的 集合的创建 >>>set_ ...

  3. javaweb之Cookie学习

    Cookie简介 HTTP是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分中两次请求是否由一个客户端发出.这样的设计严重阻碍的Web程序的设计.如:在我们进行网购时,买了一条裤子, ...

  4. HTML,CSS笔记

    text-indent 属性规定文本块中首行文本的缩进.允许使用负值.如果使用负值,那么首行会被缩进到左边.p{ text-indent:50px; } HTML <label> 标签的 ...

  5. MYSQL: 1292 - Truncated incorrect DOUBLE value: '184B3C0A-C411-47F7-BE45-CE7C0818F420'

    MySQL Bugs: #63112: Truncated incorrect DOUBLE valuehttps://bugs.mysql.com/bug.php?id=63112 Error Co ...

  6. centos6.7用yum安装redis解决办法及IP限制配置

    在centos6.7用yum安装redis解决办法 - bluesky1 - 博客园 http://www.cnblogs.com/lanblogs/p/6104834.html yum instal ...

  7. Python3练习题 018:打印星号菱形

    Python的内置方法 str.center(width [, fillchar]) 就能轻而易举打印出来:str即是数量不等的星号,width即是最大宽度(7个空格),默认填充字符fillchar就 ...

  8. STL中vector、set、list和map

  9. java.io.FileNotFoundException关于使用Intellij Idea时系统找不到指定文件的解决方案

    第一种:Intellij Idea 这个智障编辑器 在用的时候 是你在这个web目录下的空文件夹他是不给你部署的 解决在空文件夹下面随便放个文件夹就行了 第二种:也是最笨的方法,但是有前提条件就是 你 ...

  10. WPF Path总结(一)

    首先来看看Path的定义,参考MSDN:绘制一系列相互连接的直线和曲线.介绍比较简单,我们再来看看备注中有些什么,Path 对象可以绘制封闭式还是开放式形状. 多个形状和甚至曲线的形状.与不 Line ...