鉴于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. YaoLingJump开发者日志(七)

      LGame用起来真是各种蛋疼,插背景都可以显示不出来.在屏幕结束后释放资源,重载该屏幕时再setbackground也不行,直接用Lpaper当background更不行,会把tilemap上的东 ...

  2. PAT L1-048 矩阵A乘以B

    https://pintia.cn/problem-sets/994805046380707840/problems/994805082313310208 给定两个矩阵A和B,要求你计算它们的乘积矩阵 ...

  3. 某一线互联网公司前端面试题总结css部分

    1,css3选择器 :not(selector) 选择页面内所有type!=text的类型: input:not([type=text]){ color: red; font-weight: bold ...

  4. js图片转换为base64

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. phpcms免登录cookies设置方案

    PHPCMS的SESSION时间长一些的解决办法修改两个文件: phpsso_server/caches/configs/system.php里的 'session_ttl' => 999999 ...

  6. WPF文件和文件夹的操作

    1.对文件的操作 private void button_chose_Click(object sender, RoutedEventArgs e) { var openFileDialog = ne ...

  7. 【Python】python-内置常量

    引言 Python的内置常量不多,只有6个,分别是True.False.None.NotImplemented.Ellipsis.__debug__ 一.True 1.True是bool类型用来表示的 ...

  8. BZOJ 2306 幸福路径(DP)

    题解来源:http://www.cnblogs.com/jianglangcaijin/p/3799494.html 最后必然是走了一条链,或者是一个环(一直绕),或者是一条链加一个环.设f[i][j ...

  9. 【bzoj2259】[Oibh]新型计算机 堆优化Dijkstra

    题目描述 Tim正在摆弄着他设计的“计算机”,他认为这台计算机原理很独特,因此利用它可以解决许多难题. 但是,有一个难题他却解决不了,是这台计算机的输入问题.新型计算机的输入也很独特,假设输入序列中有 ...

  10. 爆款PHP面试题

    $a = 3; $b = 6; if ($a = 4 || $b = 4) { $a++; $b++; } echo $a; //输出 1 echo $b; //输出 7 逛鸟哥博客,看评论区有个新手 ...