鉴于SAM要简洁一些...于是又写了一遍这题...

  不过很好呢又学到了一些新的东西...

  这里是用SA做这道题的方法

  首先还是和两个字符串的一样,为第一个字符串建SAM

  然后每一个字符串再在这个SAM上跑匹配

  然而我们最后要的答案是什么呢?

  是某个在所有字符串中匹配长度最小值最大的状态子串

  然后对于每一个字符串

  我们可以记录它在每一个状态子串上的最大匹配长度

  最后需要一个非常关键的转移

  就是用当前节点的值更新fail指针指向的节点

  比如这种情况

  如果一次匹配到左边的三个节点,一次匹配到右边的两个节点(两次匹配在不同的字符串中)

  那么显然,这两个字符串的公共子串长度为2是存在的

  但是由于我们没有转移过,fail指针指向的点没有储存前面的信息就会出错

  

  然后至于转移的顺序,我们可以按照深度顺序

  这个可以用桶排实现

 program bzoj2946;
const maxn = ;
var n,i,j,now,maxl,root,c,tot,cnt,t:longint;
s:array[..]of ansistring;
mx,fail,q,b,ans,tem:array[-..maxn]of longint;
a:array[-..maxn,-..]of longint; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; function min(a,b:longint):longint;
begin
if a<b then exit(a) else exit(b);
end; function insert(p,c:longint):longint;
var np,q,nq:longint;
begin
inc(cnt);np:=cnt;mx[np]:=mx[p]+;
while (p<>)and(a[p,c]=) do
begin
a[p,c]:=np;p:=fail[p];
end;
if p= then fail[np]:=root else
begin
q:=a[p,c];
if mx[q]=mx[p]+ then fail[np]:=q else
begin
inc(cnt);nq:=cnt;mx[nq]:=mx[p]+;
a[nq]:=a[q];
fail[nq]:=fail[q];
fail[np]:=nq;fail[q]:=nq;
while a[p,c]=q do
begin
a[p,c]:=nq;p:=fail[p];
end;
end;
end;
exit(np);
end; begin
readln(n);
for i:= to n do readln(s[i]);
cnt:=;root:=;t:=root;
for i:= to length(s[]) do t:=insert(t,ord(s[,i])-);
for i:= to cnt do ans[i]:=mx[i];
fillchar(b,sizeof(b),);
for i:= to cnt do inc(b[mx[i]]);
for i:= to cnt do inc(b[i],b[i-]);
for i:= to cnt do ans[i]:=mx[i];
for i:=cnt downto do
begin
dec(b[mx[i]]);
q[b[mx[i]]]:=i;
end;
for i:= to n do
begin
now:=root;maxl:=;
fillchar(tem,sizeof(tem),);
for j:= to length(s[i]) do
begin
c:=ord(s[i][j])-;
if a[now,c]<> then begin now:=a[now,c];inc(maxl);end else
begin
while (now<>)and(a[now,c]=) do now:=fail[now];
if now= then begin now:=root;maxl:=;end else begin maxl:=mx[now]+;now:=a[now,c];end;
end;
tem[now]:=max(tem[now],maxl);
end;
for j:=cnt downto do tem[fail[q[j]]]:=max(tem[fail[q[j]]],tem[q[j]]);
for j:= to cnt do ans[j]:=min(ans[j],tem[j]);
end;
tot:=;
for i:= to cnt do if ans[i]>tot then tot:=ans[i];
writeln(tot);
end.

  比较了一下..代码减少了三分之一,空间缩小了十分之九...最主要写起来简单多了

  SAM大法好

  

  05/.May

[BZOJ2946][Poi2000]公共串解题报告|后缀自动机的更多相关文章

  1. [BZOJ2946] [Poi2000]公共串解题报告|后缀数组

    给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 单词个数<=5,每个单词长度<=2000     尽管最近在学的是SAM...但是看到这个题还是忍不住想写SA... (其实是不 ...

  2. [codevs3160]最长公共子串解题报告|后缀自动机

    给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 样例就觉得不能更眼熟啊...好像之前用后缀数组做过一次 然后发现后缀自动机真的好好写啊...(当然当时学后缀数组的时候也这么认为... 这 ...

  3. BZOJ2946 Poi2000 公共串 【后缀自动机】

    Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单词 l 计算最长公共子串的长度 l 输出结果 Input 文件的第一行是整数 n,1<=n& ...

  4. [bzoj2946][Poi2000]公共串_后缀数组_二分

    公共串 bzoj-2946 Poi-2000 题目大意:给定$n$个字符串,求他们的最长公共子串. 注释:$1\le n\le 5$,$1\le minlen<maxlen\le 2000$. ...

  5. SPOJ1812: LCS2 - Longest Common Substring II & BZOJ2946: [Poi2000]公共串

    [传送门:SPOJ1811&BZOJ2946] 简要题意: 给出若干个字符串,求出这些字符串的最长公共子串 题解: 后缀自动机 这两道题的区别只是在于一道给出了字符串个数,一个没给,不过也差不 ...

  6. BZOJ2946 [Poi2000]公共串(后缀自动机)

    Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单词 l        计算最长公共子串的长度 l        输 ...

  7. bzoj2946 [Poi2000]公共串(SA,SAM)

    [题意] 多串求LCS.   [思路]   主要是想找一下SAM的优越感 :) velui good 后缀数组划分height需要注意不少细节 <_<,然后不停debug   [代码]   ...

  8. 【二分答案】【分块答案】【字符串哈希】【set】bzoj2946 [Poi2000]公共串

    我们二分/分块枚举答案x,暴力把除了最短的字符串以外的其他字符串的x长度子串哈希搞出来,分别扔到set里. 然后暴力枚举最短的字符串的x长度字串,查看是否在全部的set里出现过. #include&l ...

  9. bzoj2946: [Poi2000]公共串

    SAM处女题qwq #include <iostream> #include <cstdio> #include <cstring> #include <cm ...

随机推荐

  1. lol人物模型提取(四)

      在淘宝上联系了一个3d打印服务的卖家,他要我转成stl.obj.xt.xst.igs任意一种格式给他发过去,我就把它转成了obj格式给他发过去了.   然后他那边打开是这样的,没有贴图,看上去模型 ...

  2. 关于已部署的WCF服务升级的问题

    在日常的开发过程中,我们会经常迭代发布不同的版本,所以WCF服务的接口也会经常处于变动的状态,比如在传递实体类中新加一个字段.修改参数名称等等关于服务升级的问题.但是我们不可能让已发布的版本重新引用新 ...

  3. COM 自动化控制Excel应用程序

    class Program { static void Main(string[] args) { var dt = new System.Data.DataTable(); dt.Columns.A ...

  4. 特殊符号存入mysql数据库时报错:Incorrect string value: '\xF0\x9F\x98\x84\xF0\x9F的解决方法

    问题描述:从新浪微博抓取消息保存到MySQL数据中,对应数据库字段为varchar,字符编码utf-8.部分插入成功,部分插入失败,报错如标题. 在网上查询,有人说是编码问题,建议修改编码格式,比如改 ...

  5. Error:Unable to tunnel through proxy. Proxy returns "HTTP/1.1 400 Bad Request"

    (1) 网上下载了一个android应用:死活用不了,查了以下,原来是android studio版本不对,于是把android studio的版本从2.2 升级到3.0,后来发现没法升级,只能下载, ...

  6. Go语言【第十四篇】:Go语言基础总结

    Go语言类型转换 类型转换用于将一种数据类型的变量转换为另外一种类型的变量,Go语言类型转换基本格式如下: type_name(expression) type_name为类型,expression为 ...

  7. BZOJ2049:[SDOI2008]洞穴勘测——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2049 https://www.luogu.org/problemnew/show/P2147 辉辉热 ...

  8. BZOJ2705:[SDOI2012]Longge的问题——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2705 Description Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题.现在 ...

  9. ZOJ3496:Assignment——题解

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3496 题目大意:A公司从S到T运货,每条路都有一个运货上限,而B公司则有p ...

  10. BZOJ3542 DZY Loves March 【map + 线段树】

    题目链接 BZOJ3542 题解 线段树裸题,,对每一行每一列开线段树 由于坐标很大,用\(map\)维护根下标 化一下式子,只用维护区间和,区间平方和,区间存在的个数 #include<alg ...