[BZOJ2946][Poi2000]公共串解题报告|后缀自动机
鉴于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]公共串解题报告|后缀自动机的更多相关文章
- [BZOJ2946] [Poi2000]公共串解题报告|后缀数组
给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 单词个数<=5,每个单词长度<=2000 尽管最近在学的是SAM...但是看到这个题还是忍不住想写SA... (其实是不 ...
- [codevs3160]最长公共子串解题报告|后缀自动机
给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 样例就觉得不能更眼熟啊...好像之前用后缀数组做过一次 然后发现后缀自动机真的好好写啊...(当然当时学后缀数组的时候也这么认为... 这 ...
- BZOJ2946 Poi2000 公共串 【后缀自动机】
Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单词 l 计算最长公共子串的长度 l 输出结果 Input 文件的第一行是整数 n,1<=n& ...
- [bzoj2946][Poi2000]公共串_后缀数组_二分
公共串 bzoj-2946 Poi-2000 题目大意:给定$n$个字符串,求他们的最长公共子串. 注释:$1\le n\le 5$,$1\le minlen<maxlen\le 2000$. ...
- SPOJ1812: LCS2 - Longest Common Substring II & BZOJ2946: [Poi2000]公共串
[传送门:SPOJ1811&BZOJ2946] 简要题意: 给出若干个字符串,求出这些字符串的最长公共子串 题解: 后缀自动机 这两道题的区别只是在于一道给出了字符串个数,一个没给,不过也差不 ...
- BZOJ2946 [Poi2000]公共串(后缀自动机)
Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单词 l 计算最长公共子串的长度 l 输 ...
- bzoj2946 [Poi2000]公共串(SA,SAM)
[题意] 多串求LCS. [思路] 主要是想找一下SAM的优越感 :) velui good 后缀数组划分height需要注意不少细节 <_<,然后不停debug [代码] ...
- 【二分答案】【分块答案】【字符串哈希】【set】bzoj2946 [Poi2000]公共串
我们二分/分块枚举答案x,暴力把除了最短的字符串以外的其他字符串的x长度子串哈希搞出来,分别扔到set里. 然后暴力枚举最短的字符串的x长度字串,查看是否在全部的set里出现过. #include&l ...
- bzoj2946: [Poi2000]公共串
SAM处女题qwq #include <iostream> #include <cstdio> #include <cstring> #include <cm ...
随机推荐
- java—连连看GUI
1.连连看棋盘图形化 package Link; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; impo ...
- LintCode-72.中序遍历和后序遍历树构造二叉树
中序遍历和后序遍历树构造二叉树 根据中序遍历和后序遍历树构造二叉树 注意事项 你可以假设树中不存在相同数值的节点 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2] 返回如下的树: ...
- arcgis api for javascript 各个版本的SDK下载
1.首先,进入下载网站,需要登录才能下载.下载链接 2.选择需要下载的版本,进行下载.
- jsp连接MYSQL数据库教程(文字+图)
步骤: 1.在mysql官网下载JDBC驱动程序.网址:https://dev.mysql.com/downloads/connector/j/ 2.把里面的jar包(mysql-connector- ...
- ssl证书验证的问题
对于https请求,是需要ssl证书验证的请求的,所以如果在请求时如果不带ssl证书,那么可以忽略证书的验证 有三种方法去实现: 1.Requests请求: 在文档中可以看到:http://docs. ...
- Node js MySQL简单操作
//win7环境下node要先安装MySQL的相关组件(非安装MySQL数据库),在cmd命令行进入node项目目录后执行以下语句 //npm install mysql var mysql = re ...
- mysql突然无法启动的问题
经常会有这样一个情况是:mysql跑了一段时间后,某一天我们需要重启服务的时候,发现停止后并不能正常启动,会报下面这种错误 这种情况发生的原因绝大多数都是权限的问题: 因为使用了一段时间后,使用期间表 ...
- 深入学习 Redis系列
深入学习 Redis(1):Redis 内存模型 深入学习 Redis(2):持久化 深入学习 Redis(3):主从复制 深入学习 Redis(4):哨兵
- BZOJ4516:[SDOI2016]生成魔咒——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4516 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一 ...
- BZOJ2425:[HAOI2010]计数——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=2425 https://www.luogu.org/problemnew/show/P2518 你有 ...