一个串建后缀自动机, 其他串在上面跑, 然后用当前串跑的去更新全部

---------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
 
using namespace std;
 
const int maxn = 10009;
const int n = 26;
 
char s[maxn];
 
struct Node {
Node *fa, *ch[n];
int len, mx, ans;
} pool[maxn], *pt, *Root, *Last;
 
Node* newNode(int l) {
pt->fa = NULL;
pt->ans = pt->len = l;
memset(pt->ch, 0, sizeof pt->ch);
return pt++;
}
 
void InitSAM() {
pt = pool;
Last = Root = newNode(0);
}
 
void Extend(int c) {
Node *p = Last, *np = newNode(p->len + 1);
for(; p && !p->ch[c]; p = p->fa)
p->ch[c] = np;
if(!p)
np->fa = Root;
else {
Node *q = p->ch[c];
if(q->len == p->len + 1)
np->fa = q;
else {
Node *nq = newNode(p->len + 1);
memcpy(nq->ch, q->ch, sizeof q->ch);
nq->fa = q->fa;
q->fa = np->fa = nq;
for(; p && p->ch[c] == q; p = p->fa)
p->ch[c] = nq;
}
}
Last = np;
}
 
inline void upd(int &x, int t) {
if(t > x)
x = t;
}
 
int main() {
InitSAM();
int T; scanf("%d", &T);
scanf("%s", s);
for(int i = 0, n = strlen(s); i < n; i++) Extend(s[i] - 'a');
if(T == 1) {
printf("%d\n", strlen(s));
return 0;
}
while(--T) {
for(Node *o = pt; o-- != pool; ) o->mx = 0;
scanf("%s", s);
Node *t = Root;
for(int i = 0, n = strlen(s), lth = 0; i < n; i++) {
int c = s[i] - 'a';
if(t->ch[c])
upd((t = t->ch[c])->mx,++lth);
else {
for(; t && !t->ch[c]; t = t->fa);
if(!t) {
lth = 0; t = Root;
} else {
lth = t->len + 1;
upd((t = t->ch[c])->mx, lth);
}
}
}
for(Node *o = pt; o-- != pool; )
if(o->fa) upd(o->fa->mx, o->mx);
for(Node *o = pt; o-- != pool; )
o->ans = min(o->ans, o->mx);
}
int ans = 0;
for(Node *o = pt; o-- != pool; upd(ans, o->ans));
printf("%d\n", ans);
return 0;
}

---------------------------------------------------------------------------

2946: [Poi2000]公共串

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 327  Solved: 143
[Submit][Status][Discuss]

Description

 
       给出几个由小写字母构成的单词,求它们最长的公共子串的长度。
任务:
l        读入单词
l        计算最长公共子串的长度
l        输出结果
 

Input

 
文件的第一行是整数 n,1<=n<=5,表示单词的数量。接下来n行每行一个单词,只由小写字母组成,单词的长度至少为1,最大为2000。
 

Output

仅一行,一个整数,最长公共子串的长度。
 

Sample Input

3
abcb
bca
acbc

Sample Output

HINT

Source

BZOJ 2946: [Poi2000]公共串( 后缀自动机 )的更多相关文章

  1. bzoj 2946 [Poi2000]公共串——后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2946 对每个串都建一个后缀自动机,然后 dfs 其中一个自动机,记录同步的话在别的自动机上走 ...

  2. BZOJ 2946 [Poi2000]公共串 ——后缀自动机

    任意选择一个串作为模式串,构建出后缀自动机. 然后用其他的串在后缀自动机上跑匹配. 然后就到了理解后缀自动机性质的时候. 在某一个节点的最大值是可以沿着parent树上传的. 然后用dp[i][j]表 ...

  3. BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)

    题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一 ...

  4. BZOJ 2946: [Poi2000]公共串

    2946: [Poi2000]公共串 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 787  Solved: 342[Submit][Status][D ...

  5. 【bzoj2946】[Poi2000]公共串 后缀自动机

    [Poi2000]公共串 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1386  Solved: 620[Submit][Status][Discus ...

  6. BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)

    求多串的最长公共字串. 法1: 二分长度+hash 传送门 法2: 二分+后缀数组 传送门 法3: 后缀自动机 拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再 ...

  7. BZOJ2946 [Poi2000]公共串(后缀自动机)

    Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单词 l        计算最长公共子串的长度 l        输 ...

  8. bzoj 2946: [Poi2000]公共串【SAM】

    对第一个串建SAM,把剩下的串在上面跑,每次跑一个串的时候在SAM的端点上记录匹配到这的最大长度,然后对这些串跑的结果取min,然后从这些节点的min中取max就是答案 注意在一个点更新后它的祖先也会 ...

  9. 【BZOJ 2946】 2946: [Poi2000]公共串 (SAM)

    2946: [Poi2000]公共串 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1063  Solved: 469 Description      ...

随机推荐

  1. mysql 存储过程的应用

    MySQL存储过程的创建   (1). 格式 MySQL存储过程创建的格式:CREATE PROCEDURE 过程名 ([过程參数[,...]]) [特性 ...] 过程体 这里先举个样例: mysq ...

  2. javascript高级知识点——内置对象原型

    代码信息来自于http://ejohn.org/apps/learn/. 可以修改内置对象的方法. if (!Array.prototype.forEach) { Array.prototype.fo ...

  3. iOS 网络请求——get请求

    -(void)getRequest{ NSString *urlString = [NSString stringWithFormat:@"http://f1.netgears.cn:808 ...

  4. <转>eclipse如何修改dynamic web module version .

         --------------------------------------------------------------------------------------------- 原 ...

  5. Unicode字符列表

    注:除非有特别指明,否则以下符号皆属“半角”而非“全角”. 代码 显示 描述 U+0020  空格 U+0021 ! 叹号 U+0022 " 双引号 U+0023 # 井号 U+0024 $ ...

  6. vmware 使用技巧

    1.虚拟机如何进入BIOS界面? 方法: 1) 开机按F2 2) 若来不及按F2的话,可以通过以下 2. 如何让虚拟机进入安全模式? 方法:开机快速按F8 3. 当不能连接到vCenter Serve ...

  7. Vmware 克隆CentOS 网络IP配置

    在VMware里克隆出来的CentOS Linux.. ifconfig...没有看到eth0..然后重启网卡又报下面错误. 故障现象: service network restart Shuttin ...

  8. 4.java.lang.NumberFormatException(数据类型转换异常)

    字符串转换为数字异常 当试图将一个String转换为指定的数字类型,而该字符串确不满足数字类型要求的格式时,抛出该异常.如现在讲字符型的数据“123456”转换为数值型数据时,是允许的. 但是如果字符 ...

  9. RMA编码为必输

    应用 Oracle Inventory 层 Level Function 函数名 Funcgtion Name RCV_RCVTXERE 表单名 Form Name RCVTXERE 说明 Descr ...

  10. [Drools]JAVA规则引擎 -- Drools 2

    上一篇文章 http://blog.csdn.net/quzishen/archive/2011/01/25/6163012.aspx 描述了一些常用的drools的语法标签和一个模拟实例即发送积分的 ...