多串的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. HDU1022 Train Problem I 栈的模拟

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1042 栈的模拟,题目大意是已知元素次序, 判断出栈次序是否合理. 需要考虑到各种情况, 分类处理. 常 ...

  2. JAVA作业-1

    编写一个程序,用户输入两个数,求出其加减乘除,并用消息框显示计算结果. import javax.swing.JOptionPane; // import class JOptionPane publ ...

  3. CodeForces 628D Magic Numbers (数位dp)

    题意:找到[a, b]符合下列要求的数的个数. 1.该数字能被m整除 2.该数字奇数位全不为d,偶数位全为d 分析: 1.dp[当前的位数][截止到当前位所形成的数对m取余的结果][当前数位上的数字是 ...

  4. 使用 CocoStudio UI 编辑器实现《乱斗堂》设置界面

    由于是引用别人的,所以直接贴上地址了.http://www.cocoachina.com/bbs/read.php?tid=164820&fpage=7 1 游戏中必不可少的 UI 元素    ...

  5. Python的 is 运算符

    1. is运算符判断的是同一性而不是相等性. #x和y都绑定到同一个列表,而z被绑定在另外一个具有相同数值和顺序的列表上 x = y = [1, 2, 3] z = [1, 2, 3] x == y ...

  6. NSS_10 EXTJS给弹出的子窗口传递参数

    在桌面程序中, 如果需要弹出一个子面板, 并且需要传一些参数给子面板, 我通常的作法就是:在子面板添加对应的数据成员,然后一个构造函数来接收这些参数并赋值级数据成员. 实现起来非常方便. 但是在Ext ...

  7. 万能的SQLHelper帮助类

    /// <summary> /// 数据库帮助类 /// </summary> public class SQLHelper { private static string c ...

  8. 1066. Root of AVL Tree (25)

    An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child sub ...

  9. Javascript Array.prototype.some()

    当我们使用数组时,查找数组中包含某个特殊的项是非常常见的动作.下面例子是一个简单的实现: 01 planets = [ 02     "mercury", 03     " ...

  10. <亲测好使>mac os 安装mcrypt扩展

    以前安装opencart的时候倒是不需要mcrypt 这个库.但是新版本需要了.加上自己的 是mac环境.当时闲麻烦,就一直没装.这次下午就寻思给装上吧! 1.首先你要先安装xcode这个工具.不然没 ...