【BZOJ 2946】 2946: [Poi2000]公共串 (SAM)
2946: [Poi2000]公共串
Time Limit: 3 Sec Memory Limit: 128 MB
Submit: 1063 Solved: 469Description
给出几个由小写字母构成的单词,求它们最长的公共子串的长度。任务:l 读入单词l 计算最长公共子串的长度l 输出结果Input
文件的第一行是整数 n,1<=n<=5,表示单词的数量。接下来n行每行一个单词,只由小写字母组成,单词的长度至少为1,最大为2000。Output
仅一行,一个整数,最长公共子串的长度。Sample Input
3
abcb
bca
acbcSample Output
2HINT
Source
【分析】
重新学一次SAM,从刷水题开始。
同spoj1812。用第一个串建sam,然后用其他的串跑,ans存在那个点那里,做完一个串的时候还要根据parent边的拓扑序更新该点ans,最后取min即可。
当然后缀数组也是可以的。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 2010 int mymax(int x,int y) {return x>y?x:y;}
int mymin(int x,int y) {return x<y?x:y;} struct node
{
int pre,son[],step;
// node() {pre=step=0;memset(son,0,sizeof(son));}
}t[Maxn*];
int ans[Maxn*],ad[Maxn*]; struct sam
{
int last,tot;
/*void upd(int x)
{
memset(t[x].son,0,sizeof(t[x].son));
}*/
void extend(int k)
{
int np=++tot,p=last;
t[np].step=t[last].step+;
while(p&&!t[p].son[k])
{
t[p].son[k]=np;
p=t[p].pre;
}
if(!p) t[np].pre=;
else
{
int q=t[p].son[k];
if(t[q].step==t[p].step+) t[np].pre=q;
else
{
int nq=++tot;//upd(tot);
t[nq].step=t[p].step+;
memcpy(t[nq].son,t[q].son,sizeof(t[nq].son));
t[nq].pre=t[q].pre;
t[q].pre=t[np].pre=nq;
while(p&&t[p].son[k]==q)
{
t[p].son[k]=nq;
p=t[p].pre;
}
}
}
last=np;
} }sam; char s[],ss[Maxn]; int main()
{
int n;scanf("%d",&n);
scanf("%s",s);
sam.last=sam.tot=;
int l=strlen(s);
for(int i=;i<l;i++) sam.extend(s[i]-'a'+);
memset(ans,,sizeof(ans));
for(int i=;i<=n;i++)
{
scanf("%s",s);
l=strlen(s);
int nw=,sp=;
for(int j=;j<=sam.tot;j++) ad[j]=;
for(int j=;j<l;j++)
{
int ind=s[j]-'a'+;
while(nw&&!t[nw].son[ind]) nw=t[nw].pre,sp=t[nw].step;
if(t[nw].son[ind]) sp++,nw=t[nw].son[ind];
else nw=,sp=;
ad[nw]=mymax(ad[nw],sp);
}
for(int i=sam.tot;i>=;i--) ad[t[i].pre]=mymax(ad[t[i].pre],mymin(ad[i],t[t[i].pre].step));
for(int i=sam.tot;i>=;i--) ans[i]=mymin(ans[i],ad[i]);
}
int mx=;
for(int i=;i<=sam.tot;i++) if(ans[i]<=sam.tot) mx=mymax(mx,ans[i]);
printf("%d\n",mx);
return ;
}
2017-04-17 10:21:42
【BZOJ 2946】 2946: [Poi2000]公共串 (SAM)的更多相关文章
- BZOJ 2946: [Poi2000]公共串
2946: [Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 787 Solved: 342[Submit][Status][D ...
- BZOJ 2946: [Poi2000]公共串( 后缀自动机 )
一个串建后缀自动机, 其他串在上面跑, 然后用当前串跑的去更新全部 ------------------------------------------------------------------ ...
- 【bzoj2946】[Poi2000]公共串 后缀自动机
[Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1386 Solved: 620[Submit][Status][Discus ...
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单 ...
- 【BZOJ2946】[Poi2000]公共串 后缀数组+二分
[BZOJ2946][Poi2000]公共串 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单词 l 计 ...
- [POI2000] 公共串 - 后缀数组,二分
[POI2000] 公共串 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. Solution 预处理出后缀数组和高度数组,二分答案 \(k\) ,对于每一个连续的 ...
- BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)
求多串的最长公共字串. 法1: 二分长度+hash 传送门 法2: 二分+后缀数组 传送门 法3: 后缀自动机 拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再 ...
- 【BZOJ2946】公共串 [SAM]
公共串 Time Limit: 3 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 给出几个由小写字母构成的单词,求它们最 ...
- [BZOJ2946] [Poi2000]公共串解题报告|后缀数组
给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 单词个数<=5,每个单词长度<=2000 尽管最近在学的是SAM...但是看到这个题还是忍不住想写SA... (其实是不 ...
随机推荐
- HEXO与Github.io搭建个人博客
HEXO与Github.io搭建个人博客 HEXO搭建 HEXO是基于Node.JS的一款简单快速的博客框架,能够支持多线程,支持markdown,可以将生成的静态网页发布到github.io以 ...
- 千里之行始于足下,node.js 资源中文导航
响应@jiyinyiyong 号召,cnodjs 好的资源蛮多的,的确欠缺分类,在一群FAQ中,的确很容易沉下去,根据自己对node.js的理解,做成一个资源导航,PS:如果觉得合适,希望能够合并的c ...
- 【POJ】2774 Long Long Message
[题意]给定两个字符串S和T,求最长公共子串.len<=10^5. [算法]后缀自动机 [题解]对字符串S建SAM,然后令串T在S上跑匹配. 这是自动机最原本的功能——匹配,就是串T在SAM(S ...
- Calendar 日期类介绍
Calendar c = Calendar.getInstance();//创建实例 默认是当前时刻 c.get(Calendar.YEAR); c.get(Calendar.MONTH); c.ge ...
- Spring Tool Suite 配置和使用
Spring Tool Suite使用 1.下载地址: http://spring.io/tools 2.配置字符编码:UTF-8 默认的编码是ISO-8859-1的西欧文字编 1.windows-- ...
- 蓝色的PC端后台管理界面设计模板——后台
链接:http://pan.baidu.com/s/1o82hXX4 密码:x6le
- mysq配置
mysql运维 1.mysql配置文件:/etc/my.cnf mysql日记文件 :安装时候配置的,可以通过ps aux|grep mysqld 查询 ps aux|grep mysqld mysq ...
- HDFS RAID实现方案(转)
原文链接:http://blog.chinaunix.net/uid-20196318-id-3213700.html 分布式文件系统主要用于解决海量数据存储的问题,如Goolge.Facebook等 ...
- Ubuntu 各版本的几个国内更新源
Ubuntu 国内更新源(各版本通用) 前言:为了下载更方便,速度更快,我们在使用Linux系列系统时修改 apt源 为国内的源 1.复制源文件备份,以防万一 修改文件sources.list,在目录 ...
- js基础练习(四)
练习: 通过循环按行顺序为一个5×5的二维数组a赋1到25的自然数,然后输出该数组的左下半三角.试编程. 2 3 4 5 6 7 8 9 10 11 12 13 14 ...