【BZOJ】2946: [Poi2000]公共串
http://www.lydsy.com/JudgeOnline/problem.php?id=2946
题意:给n个串,求最大公共子串。(1<=n<=5,每个串长度<=2000)
#include <bits/stdc++.h>
using namespace std;
const int N=2005<<1; struct sam {
int cnt, root, last, l[N], c[N][26], f[N], p[N], mx[N], mxl[N];
sam() { cnt=0; root=last=++cnt; }
void add(int x) {
int now=last, a=++cnt; last=a;
l[a]=l[now]+1;
for(; now && !c[now][x]; now=f[now]) c[now][x]=a;
if(!now) { f[a]=root; return; }
int q=c[now][x];
if(l[q]==l[now]+1) { f[a]=q; return; }
int b=++cnt;
memcpy(c[b], c[q], sizeof c[q]);
l[b]=l[now]+1;
f[b]=f[q];
f[q]=f[a]=b;
for(; now && c[now][x]==q; now=f[now]) c[now][x]=b;
}
void build(char *s) {
int len=strlen(s);
for(int i=0; i<len; ++i) add(s[i]-'a');
for(int i=1; i<=cnt; ++i) mx[l[i]]++;
for(int i=1; i<=len; ++i) mx[i]+=mx[i-1];
for(int i=1; i<=cnt; ++i) p[mx[l[i]]--]=i;
for(int i=1; i<=cnt; ++i) mx[i]=l[i];
}
void find(char *s) {
int x, now=root, t=0, len=strlen(s);
for(int i=0; i<len; ++i) {
x=s[i]-'a';
if(c[now][x]) ++t, now=c[now][x];
else {
while(now && !c[now][x]) now=f[now];
if(!now) t=0, now=root;
else t=l[now]+1, now=c[now][x];
}
mxl[now]=max(mxl[now], t);
}
for(int i=cnt; i; --i) {
x=p[i];
mx[x]=min(mx[x], mxl[x]);
if(mxl[x] && f[x]) mxl[f[x]]=l[f[x]];
mxl[x]=0;
}
}
int getans() {
int ret=0;
for(int i=1; i<=cnt; ++i) ret=max(ret, mx[i]);
return ret;
}
}solver; char s[N];
int main() {
int n;
scanf("%d", &n);
scanf("%s", s);
solver.build(s); --n;
while(n--) scanf("%s", s), solver.find(s);
printf("%d\n", solver.getans());
return 0;
}
复习了下sam....
【BZOJ】2946: [Poi2000]公共串的更多相关文章
- BZOJ 2946: [Poi2000]公共串
2946: [Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 787 Solved: 342[Submit][Status][D ...
- BZOJ 2946: [Poi2000]公共串( 后缀自动机 )
一个串建后缀自动机, 其他串在上面跑, 然后用当前串跑的去更新全部 ------------------------------------------------------------------ ...
- bzoj 2946 [Poi2000]公共串——后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2946 对每个串都建一个后缀自动机,然后 dfs 其中一个自动机,记录同步的话在别的自动机上走 ...
- BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)
求多串的最长公共字串. 法1: 二分长度+hash 传送门 法2: 二分+后缀数组 传送门 法3: 后缀自动机 拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再 ...
- BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)
题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一 ...
- BZOJ 2946 [Poi2000]公共串 ——后缀自动机
任意选择一个串作为模式串,构建出后缀自动机. 然后用其他的串在后缀自动机上跑匹配. 然后就到了理解后缀自动机性质的时候. 在某一个节点的最大值是可以沿着parent树上传的. 然后用dp[i][j]表 ...
- bzoj 2946: [Poi2000]公共串【SAM】
对第一个串建SAM,把剩下的串在上面跑,每次跑一个串的时候在SAM的端点上记录匹配到这的最大长度,然后对这些串跑的结果取min,然后从这些节点的min中取max就是答案 注意在一个点更新后它的祖先也会 ...
- 【BZOJ 2946】 2946: [Poi2000]公共串 (SAM)
2946: [Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1063 Solved: 469 Description ...
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单 ...
随机推荐
- 【消息队列MQ】各类MQ比较
目录(?)[-] RabbitMQ Redis ZeroMQ ActiveMQ JafkaKafka 目前业界有很多MQ产品,我们作如下对比: RabbitMQ 是使用Erlang编写的一个开源的消息 ...
- RabbitMQ消息队列:ACK机制
每个Consumer可能需要一段时间才能处理完收到的数据.如果在这个过程中,Consumer出错了,异常退出了,而数据还没有处理完成,那么 非常不幸,这段数据就丢失了. 因为我们采用no-ack的方式 ...
- CI框架初探
2014年7月3日 17:39:35 简易版: index.php->codeIgniter.php->找到控制器类文件并include->创建实例->执行成员函数 详细版本: ...
- 【贪心】最大乘积-贪心-高精度-java
问题 G: [贪心]最大乘积 时间限制: 1 Sec 内存限制: 128 MB提交: 34 解决: 10[提交][状态][讨论版] 题目描述 一个正整数一般可以分为几个互不相同的自然数的和,如3 ...
- DP:Apple Catching(POJ 2385)
牛如何吃苹果 问题大意:一个叫Bessie的牛,可以吃苹果,然后有两棵树,树上苹果每分钟会掉一个,这只牛一分钟可以在两棵树中往返吃苹果(且不吃地上的),然后折返只能是有限次W,问你这只叫Bessie的 ...
- google maps js v3 api教程(1) -- 创建一个地图
原文地址 google maps javascript官方文档:https://developers.google.com/maps/documentation/javascript/ 在创建地图之前 ...
- discuz 学习
一.Discuz首页“今日”“昨日”“欢迎新会员”等文字删除添加 搜索templeta/default/forum/discuz.htm (使用非默认模版的请修改当前使用模版的discuz.htm ...
- 配置无线网络的时候会提示“Enter Password for Default Keyring to Unlock”
密钥管理软件Seahorse有关,这个时候我们打开c配置一下就可以解决. 命令行下运行seahorse或依次点击菜单“应用程序→附件→密码和加密密钥”, 在login一行中右键选择更改密码,然后什么都 ...
- CentOS 6.5 下安装 Kibana5
1. 导入Elastic PGP Key 执行命令 rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch 2. 安装Kiban ...
- Android中几种定位 方式
介绍的几种定位方式 http://www.cnblogs.com/cuihongyu3503319/p/3863867.html 百度地图api: http://lbsyun.baidu.com/in ...