[POI 2000] 公共串
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=2946
[算法]
建立多串后缀树
对于后缀树上的每个点 , 判断该节点所代表的等价类是否在所以字符串中出现 , 用该点的深度更新答案
时间复杂度 : O(NL)
[代码]
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N = 1e5 + ;
const int ALPHA = ; int n , ans;
char s[N]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
} struct Suffix_Automaton
{
int sz , last;
int father[N] , child[N][ALPHA] , depth[N];
bool lab[N][];
vector< int > a[N];
Suffix_Automaton()
{
sz = ;
last = ;
}
inline int new_node(int dep)
{
depth[++sz] = dep;
father[sz] = ;
memset(child[sz] , , sizeof(child[sz]));
memset(lab[sz] , , sizeof(lab[sz]));
return sz;
}
inline void extend(int ch , int c)
{
int np = child[last][ch];
if (np)
{
if (depth[np] == depth[last] + )
{
lab[np][c] = true;
last = np;
} else
{
int nq = new_node(depth[last] + );
father[nq] = father[np];
father[np] = nq;
memcpy(child[nq] , child[np] , sizeof(child[nq]));
for (int p = last; child[p][ch] == np; p = father[p])
child[p][ch] = nq;
lab[nq][c] = true;
last = nq;
}
} else
{
int np = new_node(depth[last] + );
int p = last;
while (child[p][ch] == )
{
child[p][ch] = np;
p = father[p];
}
if (child[p][ch] == np)
{
father[np] = ;
lab[np][c] = true;
last = np;
return;
}
int q = child[p][ch];
if (depth[q] == depth[p] + )
{
father[np] = q;
lab[np][c] = true;
last = np;
return;
} else
{
int nq = new_node(depth[p] + );
father[nq] = father[q];
father[np] = father[q] = nq;
memcpy(child[nq] , child[q] , sizeof(child[q]));
while (child[p][ch] == q)
{
child[p][ch] = nq;
p = father[p];
}
lab[np][c] = true;
last = np;
return;
}
}
}
inline void insert(char *s , int col)
{
last = ;
for (int i = ; i <= strlen(s + ); ++i)
extend(s[i] - 'a' , col);
}
inline void dfs(int u)
{
for (unsigned i = ; i < a[u].size(); ++i)
{
int v = a[u][i];
dfs(v);
for (int j = ; j <= n; ++j)
lab[u][j] |= lab[v][j];
}
bool all = true;
for (int i = ; i <= n; ++i) all &= lab[u][i];
if (all) chkmax(ans , depth[u]);
}
inline void work()
{
for (int i = ; i <= sz; ++i)
a[father[i]].push_back(i);
dfs();
}
} SAM; int main()
{ read(n);
for (int i = ; i <= n; ++i)
{
scanf("%s" , s + );
SAM.insert(s , i);
}
SAM.work();
printf("%d\n" , ans); return ; }
[POI 2000] 公共串的更多相关文章
- BZOJ 2946: [Poi2000]公共串
2946: [Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 787 Solved: 342[Submit][Status][D ...
- BZOJ 2946: [Poi2000]公共串( 后缀自动机 )
一个串建后缀自动机, 其他串在上面跑, 然后用当前串跑的去更新全部 ------------------------------------------------------------------ ...
- 【BZOJ2946】公共串(后缀数组)
[BZOJ2946]公共串(后缀数组) 题面 权限题... 只有CJOJ题面啦 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: 读入单词,计算最长公共子串的 ...
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单 ...
- 【BZOJ】【2946】【POI2000】公共串
后缀数组 好感动,复习了下后缀数组居然写出来了……(感谢ykz大神) 求最长公共子串……WA了一发是因为:[不同字符串之间要用不同的特殊字符隔开]否则就会匹配到相同→_→比如都是aaa结尾,如果用相同 ...
- 【BZOJ2946】[Poi2000]公共串 后缀数组+二分
[BZOJ2946][Poi2000]公共串 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单词 l 计 ...
- 【BZOJ 2946】 2946: [Poi2000]公共串 (SAM)
2946: [Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1063 Solved: 469 Description ...
- 【BZOJ2946】公共串 [SAM]
公共串 Time Limit: 3 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 给出几个由小写字母构成的单词,求它们最 ...
- [BZOJ2946] [Poi2000]公共串解题报告|后缀数组
给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 单词个数<=5,每个单词长度<=2000 尽管最近在学的是SAM...但是看到这个题还是忍不住想写SA... (其实是不 ...
随机推荐
- 封装CLLocationManager定位获取经纬度
创建调用方法,在.h文件里 #import <Foundation/Foundation.h> @interface RMMapLocation : NSObject { void (^s ...
- Java中的线程池ExecutorService
示例 import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.u ...
- golang中字符串的查找方法小结
1)func Contains(s, substr string) bool这个函数是查找某个字符是否在这个字符串中存在,存在返回true 示例如下: import ( "fmt" ...
- java 邮件(2)
/** * 方法描述:发送带附件的邮件 * * @throws UnsupportedEncodingException */ public static boolean sendEmai ...
- python 基础 4.4 生成式 生成器 迭代器
一.生成式和生成器 列表生成式是python受欢迎的语法之一,通过一句简洁的语法就可以对一组元素进行过滤,还可以对得到的元素进行转换处理. #/usr/bin/python #coding=u ...
- 基于传统IPC基础上的RTMP互联网推流摄像机方案设计
在我之前的一篇博客<EasyRTMP内置进入摄像机中实现网络推流直播摄像机的功能>中,我阐述了一种将RTMP推流内置到摄像机系统内部,实现安防摄像机转互联网直播的RTMP推流摄像机功能,如 ...
- Ajax学习笔记(2)--load()方法
<head runat="server"> <title></title> <script src="http://localh ...
- formData.append("username", "Groucho"); input 文件大小
formData.append("username", "Groucho"); https://developer.mozilla.org/en-US/docs ...
- coreseek中文搜索
coreseek的安装和使用 准备软件包 coreseek-3.2.14.tar.gz 其他汁源 coreseek中文索引-示例文件.zip sphinx配置文件详解.txt 1.安装组件 yum - ...
- python cookbook第三版学习笔记六:迭代器与生成器
假如我们有一个列表 items=[1,2,3].我们要遍历这个列表我们会用下面的方式 For i in items: Print i 首先介绍几个概念:容器,可迭代对象,迭代器 容器是一种存储数据 ...