【题目链接】

  http://www.spoj.com/problems/LCS2/en/

【题意】

  求若干个串的最长公共子串。

【思路】

  SAM+DP

  先拿个串建个SAM,然后用后面的串匹配,每次将所有的匹配长度记录在状态上取min,然后对所有状态取max即答案。

  需要更新fa,因为fa[p]一定比p更优,但匹配的时候可能只更新了p而没有更新fa[p],所以还需要递推一边。

  注意mn[p]初始化为l[p]

【代码】

 #include<cstdio>
#include<cstring>
using namespace std; const int N = *1e5+; char s[N];
int sz,last,root,l[N],ch[N][],fa[N],mn[N],mx[N];
int b[N],cnt[N];
void add(int x) {
int c=s[x]-'a';
int p=last,np=++sz; last=np;
l[np]=mn[np]=x+;
for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
if(!p) fa[np]=root;
else {
int q=ch[p][c];
if(l[p]+==l[q]) fa[np]=q;
else {
int nq=++sz; l[nq]=mn[nq]=l[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];
fa[np]=fa[q]=nq;
for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
}
}
} int main() {
root=last=++sz;
scanf("%s",s);
int len=strlen(s);
for(int i=;i<len;i++) add(i);
for(int i=;i<=sz;i++) cnt[l[i]]++;
for(int i=;i<=len;i++) cnt[i]+=cnt[i-];
for(int i=;i<=sz;i++) b[cnt[l[i]]--]=i;
while(scanf("%s",s)==) {
int p=root; len=;
for(int i=;s[i];i++) {
int c=s[i]-'a';
if(ch[p][c]) { len++; p=ch[p][c]; }
else {
while(p&&!ch[p][c]) p=fa[p];
if(!p) { len=; p=root; }
else { len=l[p]+; p=ch[p][c]; }
}
if(len>mx[p]) mx[p]=len;
}
for(int i=sz;i;i--) {
p=b[i];
if(mx[p]<mn[p]) mn[p]=mx[p];
if(fa[p] && mx[fa[p]]<mx[p]) mx[fa[p]]=mx[p];
mx[p]=;
}
}
int ans=;
for(int i=;i<=sz;i++)
if(mn[i]>ans) ans=mn[i];
printf("%d",ans);
return ;
}

spoj 1812 LCS2(SAM+DP)的更多相关文章

  1. CF1120 C. Compress String(SAM+DP)

    有方程dp[i]=min(dp[i-1]+A,dp[j]+B):如果s[j+1,i]在s[i,j]中出现,所以我们就是要知道每个子串在s出现的第一个位置,这个可以hash实现或者sam,或者kmp实现 ...

  2. [HAOI2016]找相同字符(SAM+DP)

    感觉很水. 因为SAM上一个点的子树大小代表这个点所表示子串的出现次数. 建出广义后缀自动机之后.在\(parent\)树上跑\(DP\),维护\(size[i][1]\),和\(size[i][0] ...

  3. SPOJ 1812 LCS2 [后缀自动机 DP]

    题意: 求多个串<=10的最长连续子串 一个串建SAM,然后其他串在上面走 每个状态记录所有串在这个状态的公共子串的最小值 一个串在上面走的时候记录与每个状态公共子串的最大值,注意出现次数向父亲 ...

  4. 【SPOJ】Substrings(后缀自动机)

    [SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(rig ...

  5. spoj 1812 LCS2 - Longest Common Substring II (后缀自己主动机)

    spoj 1812 LCS2 - Longest Common Substring II 题意: 给出最多n个字符串A[1], ..., A[n], 求这n个字符串的最长公共子串. 限制: 1 < ...

  6. ACdreamOJ 1154 Lowbit Sum (数字dp)

    ACdreamOJ 1154 Lowbit Sum (数位dp) ACM 题目地址:pid=1154" target="_blank" style="color ...

  7. 「SDOI2016」储能表(数位dp)

    「SDOI2016」储能表(数位dp) 神仙数位 \(dp\) 系列 可能我做题做得少 \(QAQ\) \(f[i][0/1][0/1][0/1]\) 表示第 \(i\) 位 \(n\) 是否到达上界 ...

  8. 【HDU1693】Eat the Trees(插头dp)

    [HDU1693]Eat the Trees(插头dp) 题面 HDU Vjudge 大概就是网格图上有些点不能走,现在要找到若干条不相交的哈密顿回路使得所有格子都恰好被走过一遍. 题解 这题的弱化版 ...

  9. 【BZOJ1814】Ural 1519 Formula 1 (插头dp)

    [BZOJ1814]Ural 1519 Formula 1 (插头dp) 题面 BZOJ Vjudge 题解 戳这里 上面那个链接里面写的非常好啦. 然后说几个点吧. 首先是关于为什么只需要考虑三进制 ...

随机推荐

  1. Python OptionParser学习

    from optparse import OptionParser import sys def main(): p = OptionParser() p.add_option('-n','--nam ...

  2. hdu 1251 统计难题 trie入门

    统计难题 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本 ...

  3. Source Insight 显示中文乱码

    Source Insight 3.X utf8支持插件震撼发布 继上次SI多标签插件之后,因为公司内部编码改为utf8编码,因此特意做了这个Source Insight 3.X utf8插件. 下载地 ...

  4. 学无止境,学习AJAX,跨域(三)

    学习AJAX其实有个很重要的应用,就是为了执行另外几个站点的ASP,返回结果. 真正用起来,发现2个问题,>_> 不许笑,一向做DELPHI,接触ASP不多的我,的确问题大堆. 第一个问题 ...

  5. C# List<> 删除

    List<string> l = new List<string>() { "A1", "A2", "A3", &q ...

  6. responsive design

    http://www.chinaz.com/manage/2011/1121/221607.shtml http://alistapart.com/article/responsive-web-des ...

  7. RubyCritic:一款不错的检测代码质量工具

    关注代码质量是高效开发必须要做的一件事,那么在 Ruby 开发的过程中,是否有什么好的代码质量检测工具呢?下面由 Ruby 工程师路英瑞介绍一下 RubyCritic--一款还不错的代码质量检测工具. ...

  8. 如何避免远程循环执行SSH时,到第一条之后就退出

    RT 今天遇到的小问题,记录下来. 据说关键是加  < /dev/null 我也是看网上别人说的,测试成功. #!/bin/bash while read line do echo $line ...

  9. php 使用jquery实现ajax

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  10. HDU Traffic Real Time Query System

    题目大意是:对于(n, m)的图,给定边a, b查询从a到b要经过的割点的最少数目. 先tarjan算法求双连通然后缩点,即对于每个割点将周围的每个双连通看成一个点与之相连.然后求解LCA即可,距离d ...