求多串的最长公共字串.

法1: 二分长度+hash 传送门

法2: 二分+后缀数组 传送门

法3: 后缀自动机

拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再在全局取最小值(因为是所有串的公共串)就行了.

CODE

#include<bits/stdc++.h>
using namespace std;
char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
template<class T>inline void read(T &res) {
char ch; int flg = 1; while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
for(res=ch-'0';isdigit(ch=getchar());res=res*10+ch-'0'); res*=flg;
}
const int MAXN = 2005;
const int C = 26;
int m, lk[MAXN<<1], ch[MAXN<<1][C], len[MAXN<<1], mx[MAXN<<1], mn[MAXN<<1], bin[MAXN<<1], seq[MAXN<<1], sz, last;
inline void init() {
last = sz = 0; ++sz;
lk[0] = -1; len[0] = 0;
}
inline void Copy(int A, int B) {
lk[A] = lk[B];
memcpy(ch[A], ch[B], sizeof ch[B]);
}
inline int insert(int p, int c) {
int cur = sz++; last = cur;
len[cur] = len[p] + 1;
for(; ~p && !ch[p][c]; p = lk[p]) ch[p][c] = cur;
if(p == -1) lk[cur] = 0;
else {
int q = ch[p][c];
if(len[p] + 1 == len[q]) lk[cur] = q;
else {
int x = sz++;
len[x] = len[p] + 1;
Copy(x, q);
lk[cur] = lk[q] = x;
for(; ~p && ch[p][c] == q; p = lk[p]) ch[p][c] = x;
}
}
return last;
}
inline void Match(char *s) {
int p = 0, now = 0, j = 0;
for(int c; s[j]; ++j) {
if(ch[p][c=s[j]-'a'])
++now, p = ch[p][c];
else {
for(; ~p && !ch[p][c]; p = lk[p]);
if(p == -1) now = p = 0;
else now = len[p] + 1, p = ch[p][c];
}
mx[p] = max(mx[p], now);
}
for(int i = sz-1; i; --i) {
mn[seq[i]] = min(mn[seq[i]], mx[seq[i]]);
mx[lk[seq[i]]] = max(mx[lk[seq[i]]], mx[seq[i]]);
mx[seq[i]] = 0;
}
}
char s[MAXN];
int main() {
read(m); scanf("%s", s);
if(--m == 0) return printf("%d\n", strlen(s)), 0;
init(); int p = 0;
for(int i = 0; s[i]; ++i) p = insert(p, s[i]-'a');
for(int i = 0; i < sz; ++i) ++bin[mn[i] = len[i]];
for(int i = 1; i < sz; ++i) bin[i] += bin[i-1];
for(int i = sz-1; ~i; --i) seq[--bin[len[i]]] = i;
while(m--) scanf("%s", s), Match(s);
int ans = 0;
for(int i = 1; i < sz; ++i)
ans = max(ans, mn[i]);
printf("%d\n", ans);
}

BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)的更多相关文章

  1. BZOJ 2946: [Poi2000]公共串

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

  2. BZOJ 2946: [Poi2000]公共串( 后缀自动机 )

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

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

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

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

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

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

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

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

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

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

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

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

    http://www.lydsy.com/JudgeOnline/problem.php?id=2946 题意:给n个串,求最大公共子串.(1<=n<=5,每个串长度<=2000) ...

  9. BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案

    BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单 ...

随机推荐

  1. mysql数据库设计字符类型及长度

    1.数字类型 小数的我就不聊了,因为有小数点的一般都是用字符串保存.关于整数,有几种可以选TINYINT.SMALLINT.MEDIUMINT.INT和BIGINT,分别占1.2.4.8字节.如果无符 ...

  2. SqlServer判断表中某列是否包含中文,英文,纯数字

    原文:SqlServer判断表中某列是否包含中文,英文,纯数字 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog ...

  3. ApplicationListener原理分析

    在 Nacos配置服务原理 文中结束时提到过通过发布 ApplicationListener 刷新事件完成 Context 中属性值的更新.那么本章我们一起分析 ApplicationListener ...

  4. PAT A1036 Boys vs Girls(25)

    AC代码 #include <cstdio> #include <algorithm> using namespace std; const int max_n = 11000 ...

  5. 从入门到自闭之Python--Redis

    什么是Redis Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库.Redis全称为:Remote Dictionary Server ...

  6. 小白学习django第一站-环境配置

    Django简单来说就是用Python开发的一个免费开源的Web框架 使用Django,使你能够以最小的代价构建和维护高质量的Web应用. 开搞!!! 工具准备: linux(ubuntu) + py ...

  7. java8 List对象集合去重

    //测试数据 WaterMeter w0 = new WaterMeter(); WaterMeter w1 = new WaterMeter(); WaterMeter w2 = new Water ...

  8. Spring实战(十三)Spring事务

    1.什么是事务(Transaction)? 事务是指逻辑上的一组操作,要么全部成功,要么全部失败. 事务是指将一系列数据操作捆绑成为一个整体进行统一管理.如果某一事务执行成功,则该事务中进行的所有数据 ...

  9. Scala学习四——映射和数组

    一.本章要点 Scala有十分易用的语言来创建,查询和遍历映射 你需要从可变和不可变的映射中做出选择 默认情况下,你得到的是一个哈希映射,不过你也可以指明要树形映射 你可以很容易地在Scala映射和J ...

  10. SharePoint 创建页面布局

    一.前言 文章成体系,如果有不明白的地方请查看前面的文章. 二.目录 1.创建页面布局 2.首次使用页面布局 3.修改页面布局 4.使用页面布局 5.最终效果 1.创建页面布局 (1)打开设计管理器, ...