题目链接:http://poj.org/problem?id=2774

后缀数组真的太强大了,原本dp是O(nm)的复杂度,在这里只需要O(n+m)。

做法:将两个串中间夹一个未出现过的字符接起来,然后做一次后缀数组,得到的height相邻两个排名的后缀,在串中的位置如果满足在分界符左右两侧,就更新最长公共前缀。最后得到的最大值就是最长公共子序列。

#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std; const int MAXN = *;
#define F(x) ((x)/3+((x)%3==1?0:tb))
#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
int wa[MAXN*],wb[MAXN*],wv[MAXN*],wss[MAXN*];
int c0(int *r,int a,int b)
{
return r[a] == r[b] && r[a+] == r[b+] && r[a+] == r[b+];
}
int c12(int k,int *r,int a,int b)
{
if(k == )
return r[a] < r[b] || ( r[a] == r[b] && c12(,r,a+,b+) );
else return r[a] < r[b] || ( r[a] == r[b] && wv[a+] < wv[b+] );
}
void sort(int *r,int *a,int *b,int n,int m)
{
int i;
for(i = ; i < n; i++)wv[i] = r[a[i]];
for(i = ; i < m; i++)wss[i] = ;
for(i = ; i < n; i++)wss[wv[i]]++;
for(i = ; i < m; i++)wss[i] += wss[i-];
for(i = n-; i >= ; i--)
b[--wss[wv[i]]] = a[i];
}
void dc3(int *r,int *sa,int n,int m)
{
int i, j, *rn = r + n;
int *san = sa + n, ta = , tb = (n+)/, tbc = , p;
r[n] = r[n+] = ;
for(i = ; i < n; i++)if(i % != )wa[tbc++] = i;
sort(r + , wa, wb, tbc, m);
sort(r + , wb, wa, tbc, m);
sort(r, wa, wb, tbc, m);
for(p = , rn[F(wb[])] = , i = ; i < tbc; i++)
rn[F(wb[i])] = c0(r, wb[i-], wb[i]) ? p - : p++;
if(p < tbc)dc3(rn,san,tbc,p);
else for(i = ; i < tbc; i++)san[rn[i]] = i;
for(i = ; i < tbc; i++) if(san[i] < tb)wb[ta++] = san[i] * ;
if(n % == )wb[ta++] = n - ;
sort(r, wb, wa, ta, m);
for(i = ; i < tbc; i++)wv[wb[i] = G(san[i])] = i;
for(i = , j = , p = ; i < ta && j < tbc; p++)
sa[p] = c12(wb[j] % , r, wa[i], wb[j]) ? wa[i++] : wb[j++];
for(; i < ta; p++)sa[p] = wa[i++];
for(; j < tbc; p++)sa[p] = wb[j++];
}
void da(int str[],int sa[],int rank[],int height[],int n,int m)
{
for(int i = n; i < n*; i++)
str[i] = ;
dc3(str, sa, n+, m);
int i,j,k = ;
for(i = ; i <= n; i++)rank[sa[i]] = i;
for(i = ; i < n; i++)
{
if(k) k--;
j = sa[rank[i]-];
while(str[i+k] == str[j+k]) k++;
height[rank[i]] = k;
}
} int str[MAXN*],sa[MAXN*],rk[MAXN],height[MAXN]; char s1[MAXN],s2[MAXN];
int l1,l2; int main()
{
while (~scanf("%s%s",s1,s2))
{
l1=strlen(s1);
l2=strlen(s2);
for (int i=; i<l1; i++) str[i]=s1[i]-'a'+;
str[l1]=;
for (int i=;i<l2;i++) str[l1++i]=s2[i]-'a'+;
str[l1+l2+]=;
da(str,sa,rk,height,l1+l2+,);
int ma=;
for (int i=;i<=l1+l2+;i++)
{
int p1=sa[i-];
int p2=sa[i];
if (p1<l1&&p2>l1 || p1>l1&&p2<l1) ma=max(ma,height[i]);
}
printf("%d\n",ma);
}
return ;
}

[poj 2274]后缀数组+最长公共子串的更多相关文章

  1. POJ 2217 (后缀数组+最长公共子串)

    题目链接: http://poj.org/problem?id=2217 题目大意: 求两个串的最长公共子串,注意子串是连续的,而子序列可以不连续. 解题思路: 后缀数组解法是这类问题的模板解法. 对 ...

  2. POJ-2774-Long Long Message(后缀数组-最长公共子串)

    题意: 给定两个字符串 A 和 B,求最长公共子串. 分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长公共子串等价于求 A 的后缀和 B 的后缀的最长公共前缀的最大 ...

  3. POJ3294 Life Forms —— 后缀数组 最长公共子串

    题目链接:https://vjudge.net/problem/POJ-3294 Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total ...

  4. POJ 2774 (后缀数组 最长公共字串) Long Long Message

    用一个特殊字符将两个字符串连接起来,然后找最大的height,而且要求这两个相邻的后缀的第一个字符不能在同一个字符串中. #include <cstdio> #include <cs ...

  5. POJ 3294 Life Forms [最长公共子串加强版 后缀数组 && 二分]

    题目:http://poj.org/problem?id=3294 Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submiss ...

  6. poj 1458 Common Subsequence_最长公共子串

    题意:略 求最长公共子串 #include<iostream> #include<cstdio> #include<string> using namespace ...

  7. POJ3415 Common Substrings —— 后缀数组 + 单调栈 公共子串个数

    题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS   Memory Limit: 65536K ...

  8. CSU1632Repeated Substrings(后缀数组/最长公共前缀)

    题意就是求一个字符串的重复出现(出现次数>=2)的不同子串的个数. 标准解法是后缀数组.最长公共前缀的应用,对于样例aabaab,先将所有后缀排序: aab 3    aabaab 1    a ...

  9. POJ3450 Corporate Identity —— 后缀数组 最长公共子序列

    题目链接:https://vjudge.net/problem/POJ-3450 Corporate Identity Time Limit: 3000MS   Memory Limit: 65536 ...

随机推荐

  1. python3 练习题100例 (二十三)与7相关的数

    与7相关的数:如果一个正整数,它能被7整除或者它的十进制表示法中某个位数上的数字为7,则称之为与7相关的数.(10分) 题目内容: 现在我们给定一个正整数n(n<1000),求所有小于等于n的与 ...

  2. python生成器详解

    1. 生成器 利用迭代器(迭代器详解python迭代器详解),我们可以在每次迭代获取数据(通过next()方法)时按照特定的规律进行生成.但是我们在实现一个迭代器时,关于当前迭代到的状态需要我们自己记 ...

  3. go学习笔记-语言基础

    语言基础 结构 基础组成: 包声明 引入包 函数 变量 语句 & 表达式 注释 程序 在开始编写应用之前,我们先从最基本的程序开始,在学习大部分语言之前,都会编写一个可以输出hello wor ...

  4. (数据科学学习手札06)Python在数据框操作上的总结(初级篇)

    数据框(Dataframe)作为一种十分标准的数据结构,是数据分析中最常用的数据结构,在Python和R中各有对数据框的不同定义和操作. Python 本文涉及Python数据框,为了更好的视觉效果, ...

  5. 初步学习pg_control文件之六

    接前文:初步学习pg_control文件之五 ,DB_IN_ARCHIVE_RECOVERY何时出现? 看代码:如果recovery.conf文件存在,则返回 InArchiveRecovery = ...

  6. spring boot 入门3 如何在springboot 上使用AOP

    Aop是spring的两大核心之一 那么如何在springboot中采用注解的形式实现aop那? 1)首先我们定义一个相关功能的切面类 并 采用@Aspect 注解来声明当前类为切面 同时采用@Com ...

  7. Django笔记 —— 模型高级进阶

    最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...

  8. java存储位置经典例子

    String a="a";String b="b";String c="ab";String d="ab";String ...

  9. 步骤2:JMeter 分布式测试(性能测试大并发、远程启动解决方案)

    转载(记录) http://www.cnblogs.com/fengpingfan/p/5583954.html http://www.cnblogs.com/puresoul/p/4844539.h ...

  10. Oracle修改表字段类型(number-->varchar2(len)),亲测可用

    思路: --新建临时表以存储正确的顺序create table A_2 as select (column1,colum2,……A表中的顺序) from A_1 ; --删除表A_1drop tabl ...