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

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

#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. sqlplus handbook

    1.直接敲sqlplus并回车就是启动SQL*PLUS,输入user及password将使用户登陆到缺省的数据库. 请输入用户名: 2.sqlplus user/password@SERVICE_NA ...

  2. exit函数的妙用

    写了一个程序,用来推断一个文件是否存在: #include<stdio.h> main() {  FILE *fp;  fp = fopen ("/home/wang/my/ct ...

  3. CSS中zoom和scale的区别

    zoom和scale这两个东西都是用于对元素的缩放,但两者除了兼容性之外还有一些不同的地方.zoom缩放会将元素保持在左上角,而scale默认是中间位置,可以通过transform-origin来设置 ...

  4. linux 搭建Tomcat

    这几天用虚拟机装了centos ,以前没有用过linux,先将搭建java web 环境记录如下: 一.卸载系统安装的jdk环境. 1.安装好的CentOS会自带OpenJdk,用命令 java -v ...

  5. 获取xml文件

    <?xml version="1.0" encoding="utf-8" ?><ArrayOfSystemRool xmlns:xsi=&qu ...

  6. Mantis Administrator控制密码、注册不用邮件验证、添加测试员[Z]

    Mantis默认安装完成后,管理员创建用户,但无法设置用户密码,只有通过邮件由用户自行修改.无法适应某些没有统一邮箱的情况,现将关闭邮箱验证方法和管理员设置用户密码方法验证通过   不用邮件验证: c ...

  7. C++中,new/delete和malloc/free的区别

    1.new/delete是C++的操作符,而malloc/free是C中的函数. 2.new做两件事,一是分配内存,二是调用类的构造函数:同样,delete会调用类的析构函数和释放内存.而malloc ...

  8. [poco] HttpRequest之post方法

    转自 http://www.cnblogs.com/yuanxiaoping_21cn_com/archive/2012/06/10/2544032.html #import <iostream ...

  9. 解决ie6支持最大高度最小高度的方法

    1.IE6支持max-height解决方法 IE6支持最大高度解决CSS代码:.yangshi{max-height:1000px;_height:expression((document.docum ...

  10. 关于jQuery中的$.grep()方法的使用

    数组筛选的方法,记录下,以加深印象. var ary = [1, 9, 3, 8, 6, 1, 5, 9, 4, 7, 3, 8, 6, 9, 1]; ary = $.grep(ary, functi ...