【BZOJ】2946: [Poi2000]公共串
2024-08-27 07:31:44
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....
最新文章
- Linux实战教学笔记01:计算机硬件组成与基本原理
- jQuery插件(多级菜单)
- 利用flexbox实现按字符长度排列dom元素
- CultureInfo 类
- Verilog学习笔记基本语法篇(十)&#183;&#183;&#183;&#183;&#183;&#183;&#183;&#183; 常用系统函数
- 从零开始学习Mysql的学习记录
- 关于结构化BOM的思考
- (ASP.NET)C#连接Oracle数据库示例(中文乱码问题解决)
- 关于T公司的强矩阵架构的思考
- javascript二维数组
- [ZHUAN]Flask学习记录之Flask-SQLAlchemy
- C语言学习的经典书籍--转载
- lnmp一键安装包配置laravel项目
- iOS block和代理的区别
- 照虎画猫写自己的Spring——依赖注入
- DOM节点的创建
- 2018.3.29 div格式设置
- DirectX11--深入理解与使用2D纹理资源
- 如何找回Ucenter创始人密码,账号无需修改
- 使用ubifs格式的根文件系统