[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 ...
随机推荐
- ACM 第四天
A - 最短路 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的 ...
- 往Matlab中添加工具包
使用Matlab过程中,常常会缺少一些函数包导致无法运行,会显示未定义函数. 假如我要用sigshift( ) 这个移位函数,但Matlab中没有,就会提示错误:未定义函数或变量 'sigshift' ...
- autoCAD 2008 Win7 64位, win8 64位 安装 燕秀工具箱 yanxiu.cui 文件下载
Win7 64位, win8 64位 安装 燕秀工具箱 , 提示没有权限. 网站上下载燕秀工具箱, 安装后. 提示权限不够. 解决办法如下; 1. CAD, 权限修改. 2. 下载 yanxiu.cu ...
- TCP系列31—窗口管理&流控—5、TCP流控与滑窗
一.TCP流控 之前我们介绍过TCP是基于窗口的流量控制,在TCP的发送端会维持一个发送窗口,我们假设发送窗口的大小为N比特,网络环回时延为RTT,那么在网络状况良好没有发生拥塞的情况下,发送端每个R ...
- ZOJ 1539 L-Lot
https://vjudge.net/contest/67836#problem/L Out of N soldiers, standing in one line, it is required t ...
- MySQL必备命令
来源:http://www.cnblogs.com/liushuijinger/p/3381775.html 今天跟大家分享一下MySQL从连接到具体操作的一系列常用命令.可能有的人觉得现在有很多可视 ...
- mysql中删除重复记录,并保留重复数据中的一条数据的SQL语句
正好想写一条删除重复语句并保留一条数据的SQL,网上查了一部分资料写的很详细,但还是在这里写下自己的理解,以遍后续学习 .如下: 表字段和数据: SQL语句: [sql] view plain cop ...
- WPF一个对象显示多个属性
一个对象显示多个属性使用模板的方法: 如图: <dataTemplate x:key="MyDataTemplate">
- 【WCF】WCF 附录 高级主题 配置服务配额设置
微软产品自带一个“默认安全”方案.这也包括了WCF,意味着WCF中的多种配置可以设置来阻止诸如DOS(拒绝服务访问)攻击.微软为很多基于一个单一计算机的开发环境选择这样的设置.这也意味着默认设置中的一 ...
- MySQL数据库引擎MyISAM与InnoDB的区别
1. 存储结构 MyISAM:每个MyISAM在磁盘上存储成三个文件.第一个文件的名字以表的名字开始,扩展名指出文件类型..frm文件存储表定义.数据文件的扩展名为.MYD (MYData).索引文件 ...