spoj 1811 LCS - Longest Common Substring



题意:

给出两个串S, T, 求最长公共子串。

限制:

|S|, |T| <= 1e5



思路:

dp O(n^2) 铁定超时

后缀数组 O(nlog(n)) 在spoj上没试过,感觉也会被卡掉

后缀自己主动机 O(n)





我们考虑用SAM读入字符串B;

令当前状态为s,同一时候最大匹配长度为len;

我们读入字符x。假设s有标号为x的边,那么s=trans(s,x),len = len+1;

否则我们找到s的第一个祖先a。它有标号为x的边。令s=trans(a,x),len=Max(a)+1;

假设没有这种祖先,那么令s=root,len=0;

在过程中更新状态的最大匹配长度。



详情參考clj论文

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 3 * 1e5;
char S[N], T[N]; struct SAM {
struct Node {
int fa, ch[27];
int val;
void init() {
fa = val = 0;
memset(ch, 0, sizeof(ch));
}
} node[2 * N]; int tot;
int new_node() {
node[++tot].init();
return tot;
} int root, last;
void init() {
tot = root = last = 1;
node[0].init();
node[1].init();
} void add(int x) {
int p = last;
int np = new_node(); node[np].val = node[p].val + 1;
while(p && node[p].ch[x] == 0){
node[p].ch[x] = np;
p = node[p].fa;
}
if(p == 0) node[np].fa = root;
else {
int q = node[p].ch[x];
if(node[p].val + 1 == node[q].val)
node[np].fa = q;
else {
int nq = new_node(); node[nq].val = node[p].val + 1;
memcpy(node[nq].ch, node[q].ch, sizeof(node[q].ch));
node[nq].fa = node[q].fa;
node[q].fa = node[np].fa = nq;
while(p && node[p].ch[x] == q) {
node[p].ch[x] = nq;
p = node[p].fa;
}
}
}
last = np;
}
void debug() {
for(int i = 1; i <= tot; ++i) {
printf("id=%d, fa=%d, step=%d, ch=[ ", i, node[i].fa, node[i].val);
for(int j = 0; j < 26; ++j) {
if(node[i].ch[j])
printf("%c,%d ", j+'a', node[i].ch[j]);
}
puts("]");
}
} void gao();
} sam; void SAM::gao() {
int len_s = strlen(S);
int len_t = strlen(T); init();
for(int i = 0; i < len_s; ++i) {
add(S[i] - 'a');
}
//debug();
int p = root;
int ans = 0;
int tmp = 0;
for(int i = 0; i < len_t; ++i) {
if(node[p].ch[T[i] - 'a']) {
++tmp;
p = node[p].ch[T[i] - 'a'];
} else {
while(p && node[p].ch[T[i] - 'a'] == 0)
p = node[p].fa;
if(p) {
tmp = node[p].val + 1;
p = node[p].ch[T[i] - 'a'];
} else {
p = root;
tmp = 0;
}
}
ans = max(ans, tmp);
}
printf("%d\n", ans);
} int main() {
scanf("%s%s", S, T);
sam.gao();
return 0;
}

spoj 1811 LCS - Longest Common Substring (后缀自己主动机)的更多相关文章

  1. SPOJ 1811 LCS - Longest Common Substring

    思路 和SPOJ 1812 LCS2 - Longest Common Substring II一个思路,改成两个串就有双倍经验了 代码 #include <cstdio> #includ ...

  2. 【刷题】SPOJ 1811 LCS - Longest Common Substring

    A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...

  3. SPOJ1811 LCS - Longest Common Substring(后缀自动机)

    A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...

  4. 后缀自动机(SAM) :SPOJ LCS - Longest Common Substring

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

  5. spoj 1812 LCS2 - Longest Common Substring II (后缀自己主动机)

    spoj 1812 LCS2 - Longest Common Substring II 题意: 给出最多n个字符串A[1], ..., A[n], 求这n个字符串的最长公共子串. 限制: 1 < ...

  6. spoj1811 LCS - Longest Common Substring

    地址:http://www.spoj.com/problems/LCS/ 题面: LCS - Longest Common Substring no tags  A string is finite ...

  7. 【SP1811】LCS - Longest Common Substring

    [SP1811]LCS - Longest Common Substring 题面 洛谷 题解 建好后缀自动机后从初始状态沿着现在的边匹配, 如果失配则跳它的后缀链接,因为你跳后缀链接到达的\(End ...

  8. SPOJ 10570 LONGCS - Longest Common Substring

    思路 和SPOJ 1812 LCS2 - Longest Common Substring II一个思路,改成多组数据就有三倍经验了 代码 #include <cstdio> #inclu ...

  9. SPOJ LCS Longest Common Substring 和 LG3804 【模板】后缀自动机

    Longest Common Substring 给两个串A和B,求这两个串的最长公共子串. no more than 250000 分析 参照OI wiki. 给定两个字符串 S 和 T ,求出最长 ...

随机推荐

  1. Django底层原理简介与安装

    Django环境目录搭建一栏: 利用wsgiref模块封装好的socket搭建服务端: #利用wsgiref模块封装好的socket演示操作(例如accept\recv) #也可以实现socket服务 ...

  2. TOJ2680: 最大矩阵连乘次数

    2680: 最大矩阵连乘次数  Time Limit(Common/Java):1000MS/10000MS     Memory Limit:65536KByteTotal Submit: 144 ...

  3. 【Mysql 优化 6】mysql优化的内容和思路

    根据最近做mysql优化,以及参照的官方文档的一些知识点,总结一下,如何下手去优化mysql 数据库.PS:更多可能是我个人的笔记总结记录,仅供参考 一.优化的内容 可以优化的内容,从范围的大小,可以 ...

  4. 使用Gson解析JSON数据

    本文使用gson对json进行解析处理 首先,下载gson包 ,本文使用(gson-1.6.jar) package com.whroid.java.json; import com.google.g ...

  5. 关闭chrome浏览器的input香蕉黄背景

    chrome浏览器input的自动完成,点击之后自动输入,input的背景会变成香蕉黄,用如下方法修复: /* Change the white to any color ;) 就是给input设置内 ...

  6. BeanFactory到WebApplicationContext的结构 以及bean和spring容器的关系

    BeanFactory: Ioc 容器 ApplicationContext: Spring容器 WebApplicationContext需要ServletContext实例,也就是说它必须在拥有W ...

  7. mod性质 学习笔记

    mod性质小结 \(a\equiv b(\mod m)\) $ \rightarrow \( \)a-b=k*m,k\in Z$ \(a\equiv b且c\equiv d(\mod m)\) \(\ ...

  8. POJ1167 The Buses

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6234   Accepted: 1698 Description A man ...

  9. net5:自定义验证控件服务器端验证与客户端验证的使用

    原文发布时间为:2008-07-29 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Data;using System.Configuration ...

  10. SEO总结(一)