博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SPOJ.1812.LCS2(后缀自动机)
阅读量:4591 次
发布时间:2019-06-09

本文共 1156 字,大约阅读时间需要 3 分钟。

\(Description\)

求最多10个串的LCS(最长公共子序列)。

\(Solution\)

类比上题,对一个串建SAM,我们可以逐串地求出其在每个节点所能匹配的最大长度mx[i]。

对于每个点i,所有串的mx[i]的最小值即为在点i n个串的LCS长度。枚举所有点即可。
这需要把每个点都匹配一遍求mx[]。因为fa[p]是p的上一个后缀,所有(部分)匹配了p一定可以完全匹配fa[p],而匹配p时不会沿p到根去更新一遍mx[]。
所以每匹配一个串,要按len从大到小(自叶子向根)更新一遍,即如果p(有部分)匹配了,那么mx[fa[p]]就可以更新为len[fa[p]].

//0.08s 27M#include 
#include
#include
const int N=2e5+7;char s[N>>1];struct Suffix_Automaton{ int las,tot,fa[N],son[N][26],len[N],mx[N],ans[N],tm[N],A[N]; void Insert(int c) { int p=las,np=++tot; len[las=np]=ans[np]=len[p]+1; for(; p&&!son[p][c]; p=fa[p]) son[p][c]=np; if(!p) fa[np]=1; else { int q=son[p][c]; if(len[q]==len[p]+1) fa[np]=q; else { int nq=++tot; ans[nq]=len[nq]=len[p]+1; memcpy(son[nq],son[q],sizeof son[q]); fa[nq]=fa[q], fa[q]=fa[np]=nq; for(; son[p][c]==q; p=fa[p]) son[p][c]=nq; } } } void Build(char *s) { las=tot=1; int l=strlen(s); for(int i=0; i

转载于:https://www.cnblogs.com/SovietPower/p/9114717.html

你可能感兴趣的文章
fomo6d游戏系统开发 fomo6d游戏
查看>>
div简单布局理解
查看>>
EasyUI Tree判断节点是否是叶
查看>>
Java基础加强总结(一)——注解(Annotation)
查看>>
Windows 2008R2关闭网络发现
查看>>
hibernate tool连接oracle生成pojo和xml文件无法查询表解决办法
查看>>
Jenkins执行selenium报错unknown error: cannot find Chrome binary
查看>>
Content-Type四种常见取值
查看>>
禹庙-杜甫
查看>>
Cache缓存
查看>>
[家里蹲大学数学杂志]第409期与正弦对数有关的一个积分不等式
查看>>
BZOJ 2795: [Poi2012]A Horrible Poem (Hash+思维)
查看>>
HDOJ-1002
查看>>
Tree (四校联考T1)
查看>>
javascript动态合并表格相同的单元格
查看>>
CRM项目上线第一天
查看>>
对象属性特性(可写,可枚举,可配置)
查看>>
5.16
查看>>
Dom EVENT对象
查看>>
[BZOJ3531][Sdoi2014]旅行 树链剖分
查看>>