求多串的最长公共字串.

法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);
}

最新文章

  1. dojo/dom-construct.toDom方法学习笔记
  2. Save ITCM
  3. IOS判断网络环境
  4. 使用charles 抓包
  5. UPDATE---修改表中数据
  6. linux下的进程、网络、性能监控命令
  7. Spring的事务传播机制
  8. Java中的常量治理
  9. 使用Nginx+CppCMS构建高效Web应用服务器(之三)
  10. Xshell配置密钥公钥(Public key)与私钥(Private Key)登录
  11. 关于ARMv8另外几个问题
  12. 设计模式(三)Singleton Pattern单例设计模式
  13. python low版线程池
  14. 学习Junit资料
  15. You have not concluded your merge (MERGE_HEAD exists) git拉取失败
  16. MySQL-Jira双机热备
  17. 2018.07.17 洛谷P1368 工艺(最小表示法)
  18. *(ptr++) += 123
  19. rails应用使用carrierwave和mini_magick上传用户头像
  20. python3图片验证码识别

热门文章

  1. CWMP开源代码研究——git代码工程
  2. [转帖]字符编码笔记:ASCII,Unicode 和 UTF-8
  3. python+requests 请求响应文本出错返回“登录超时”
  4. mybatis-plus 错误 java.lang.NoClassDefFoundError
  5. idea模块在maven projects中显示灰色的解决办法
  6. T100——取得系统参数值,如关帐日期
  7. Boot-crm管理系统开发教程(二)
  8. Jmeter之逻辑控制器/定时器
  9. 高性能MySQL3_笔记1_Mysql的架构与历史
  10. 怎样理解 Vue 中的计算属性 computed 和 methods ?