多串的LCS,注意要利用拓扑序更新suf的len。

我用min,max,三目会超时,所以都改成了if,else

#pragma warning(disable:4996)
#include<cstring>
#include<string>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#define maxn 100050
using namespace std; struct State{
State *suf, *go[26];
int val, len[2];
State() :suf(0), val(0){
memset(go, 0, sizeof(go));
memset(len, 0, sizeof(len));
}
}*root, *last; State statePool[maxn * 2], *cur; void init()
{
cur = statePool;
root = last = cur++;
} void extend(int w)
{
State *p = last, *np = cur++;
np->val = p->val + 1;
np->len[1] = np->val;
while (p&&!p->go[w]) p->go[w] = np, p = p->suf;
if (!p) np->suf = root;
else{
State *q = p->go[w];
if (p->val + 1 == q->val){
np->suf = q;
}
else{
State *nq = cur++;
memcpy(nq->go, q->go, sizeof q->go);
nq->val = p->val + 1;
nq->len[1] = nq->val;
nq->suf = q->suf;
q->suf = nq;
np->suf = nq;
while (p&&p->go[w] == q){
p->go[w] = nq, p = p->suf;
}
}
}
last = np;
} char str[maxn];
int n; int bcnt[maxn];
State *b[maxn * 2]; int main()
{
n = 0;
scanf("%s", str);
init();
int len = strlen(str);
for (int i = 0; i < len; i++){
extend(str[i] - 'a');
}
int tot = cur - root;
memset(bcnt, 0, sizeof(bcnt));
for (int i = 0; i < tot; i++) bcnt[statePool[i].val]++;
for (int i = 1; i <= len; i++) bcnt[i] += bcnt[i - 1];
for (int i = tot - 1; i >= 0; i--) b[--bcnt[statePool[i].val]] = &statePool[i];
while (scanf("%s", str) != EOF){
int lenb = strlen(str);
int cnt = 0;
State *p = root;
for (int i = 0; i < lenb; i++){
if (p->go[str[i] - 'a']){
cnt++;
p = p->go[str[i] - 'a'];
}
else{
while (p&&!p->go[str[i] - 'a']) p = p->suf;
if (!p) {
p = root;
cnt = 0;
}
else{
cnt = p->val + 1;
p = p->go[str[i] - 'a'];
}
}
if (cnt > p->len[0]){
p->len[0] = cnt;
}
}
for (int i = tot - 1; i >= 0; i--){
if (b[i]->len[0]<b[i]->len[1]) b[i]->len[1] = b[i]->len[0];
if (b[i]->suf&&b[i]->suf->len[0]< b[i]->len[0]){
b[i]->suf->len[0] = b[i]->len[0];
}
b[i]->len[0] = 0;
}
}
int ans = 0;
for (int i = 0; i < tot; i++){
if (ans < b[i]->len[1]){
ans = b[i]->len[1];
}
}
printf("%d\n", ans);
return 0;
}

SPOJ LCS2 后缀自动机的更多相关文章

  1. 多个串的最长公共子串 SPOJ - LCS2 后缀自动机

    题意: 求多个串的最长公共子串 这里用的是O(n)的后缀自动机写法 我后缀数组的专题有nlog(n)写法的 题解: 对于其中的一个串建立后缀自动机 然后对于后缀自动机上面的每一个节点求出每一个节点最长 ...

  2. SPOJ NSUBSTR (后缀自动机)

    SPOJ NSUBSTR Problem : 给一个长度为n的字符串,要求分别输出长度为1~n的子串的最多出现次数. Solution :首先对字符串建立后缀自动机,在根据fail指针建立出后缀树,对 ...

  3. SPOJ LCS 后缀自动机

    用后缀自动机求两个长串的最长公共子串,效果拔群.多样例的时候memset要去掉. 解题思路就是跟CLJ的一模一样啦. #pragma warning(disable:4996) #include< ...

  4. SPOJ - LCS 后缀自动机入门

    LCS - Longest Common Substring A string is finite sequence of characters over a non-empty finite set ...

  5. SPOJ LCS 后缀自动机找最大公共子串

    这里用第一个字符串构建完成后缀自动机以后 不断用第二个字符串从左往右沿着后缀自动机往前走,如能找到,那么当前匹配配数加1 如果找不到,那么就不断沿着后缀树不断往前找到所能匹配到当前字符的最大长度,然后 ...

  6. SPOJ 7258 (后缀自动机)

    转载:http://hzwer.com/4492.html 给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个. 搞出后缀自动机 dp处理出每个点往下走能 ...

  7. 长度为x的本质不同的串的出现次数 SPOJ - NSUBSTR 后缀自动机简单应用

    题意: 长度为x的本质不同的串的出现次数 题解: 先处理出每一个节点所对应的子串出现的次数 然后取max就好了 #include <set> #include <map> #i ...

  8. SPOJ.1812.LCS2(后缀自动机)

    题目链接 \(Description\) 求最多10个串的LCS(最长公共子序列). \(Solution\) 类比上题,对一个串建SAM,我们可以逐串地求出其在每个节点所能匹配的最大长度mx[i]. ...

  9. SPOJ 1812 LCS2 [后缀自动机 DP]

    题意: 求多个串<=10的最长连续子串 一个串建SAM,然后其他串在上面走 每个状态记录所有串在这个状态的公共子串的最小值 一个串在上面走的时候记录与每个状态公共子串的最大值,注意出现次数向父亲 ...

随机推荐

  1. java springmvc Log4j filter等(稍微完善一下项目)

    仅供参考-接上文 springmvc  1.设置Log4jConfigListener日志监听(可以为开发调试.发布后运行的意外调试.等) 在src/main/resources目录下新建log4j. ...

  2. 【笔记】Windows Phone 8开发笔记之API

    Windows Phone 8 API一览 Windows Phone 7平台不支持Native语言的开发,这困扰了许多游戏和底层应用的开发者.Windows Phone 8 SDK的推出,改善了这个 ...

  3. 更新win7资源管理器

    更新exeplorer.exe: 1.方法1: void RefreshExplorer() { ]; SHELLEXECUTEINFOA shellExeInfo={}; shellExeInfo. ...

  4. win8系统下保存出现闪退的解决方案

    不知道有没有人和我一样用的是win8系统,同时还遇到保存QQ截图保存闪退.保存sublime文件闪推.系统自带截图保存闪退.....更可恶的是我用chrome中百度搜索“win8保存东西闪退”结果浏览 ...

  5. linux服务器git pull/push时提示输入账号密码之免除设置

    1.先cd到根目录,执行git config --global credential.helper store命令 [root@iZ25mi9h7ayZ ~]# git config --global ...

  6. python的各种推导式(列表推导式、字典推导式、集合推导式)

    推导式comprehensions(又称解析式),是Python的一种独有特性.推导式是可以从一个数据序列构建另一个新的数据序列的结构体. 共有三种推导,在Python2和3中都有支持: 列表(lis ...

  7. thinkpad t440p 解决无线网卡驱动

    $ wget https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1239578/+attachment/4057550/+files/rtl_9 ...

  8. 【转】Mac 上 java 究竟在哪里,本文彻底让你搞清楚!

    这篇文章可能比较适合那些在经常在Mac下进行Java编程开发,或者经常使用Java工具的朋友.不关心Java或者不了解Java的朋友可以绕过本文哈~ 1. Mac下当你在[终端]输入java -ver ...

  9. SQL Server 2014 Always on ON Microsoft Azure New Portal(1)

    以前假如需要在Azure IaaS 创建的SQL Server AlwaysOn 需要参考以下的步骤 From the MVPs: SQL Server High Availability in Wi ...

  10. [转]system函数返回值探究

    对于system这个函数的功能早就有一定了解,读书期间,就学习了UNIX系统编程这本书,后来买了APUE.我这个人总是有好读书不求甚解的毛病.对于system函数只知其一,不知其二.后来被人问起相关的 ...