[poj 2274]后缀数组+最长公共子串
题目链接: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]后缀数组+最长公共子串的更多相关文章
- POJ 2217 (后缀数组+最长公共子串)
题目链接: http://poj.org/problem?id=2217 题目大意: 求两个串的最长公共子串,注意子串是连续的,而子序列可以不连续. 解题思路: 后缀数组解法是这类问题的模板解法. 对 ...
- POJ-2774-Long Long Message(后缀数组-最长公共子串)
题意: 给定两个字符串 A 和 B,求最长公共子串. 分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长公共子串等价于求 A 的后缀和 B 的后缀的最长公共前缀的最大 ...
- POJ3294 Life Forms —— 后缀数组 最长公共子串
题目链接:https://vjudge.net/problem/POJ-3294 Life Forms Time Limit: 5000MS Memory Limit: 65536K Total ...
- POJ 2774 (后缀数组 最长公共字串) Long Long Message
用一个特殊字符将两个字符串连接起来,然后找最大的height,而且要求这两个相邻的后缀的第一个字符不能在同一个字符串中. #include <cstdio> #include <cs ...
- POJ 3294 Life Forms [最长公共子串加强版 后缀数组 && 二分]
题目:http://poj.org/problem?id=3294 Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submiss ...
- poj 1458 Common Subsequence_最长公共子串
题意:略 求最长公共子串 #include<iostream> #include<cstdio> #include<string> using namespace ...
- POJ3415 Common Substrings —— 后缀数组 + 单调栈 公共子串个数
题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS Memory Limit: 65536K ...
- CSU1632Repeated Substrings(后缀数组/最长公共前缀)
题意就是求一个字符串的重复出现(出现次数>=2)的不同子串的个数. 标准解法是后缀数组.最长公共前缀的应用,对于样例aabaab,先将所有后缀排序: aab 3 aabaab 1 a ...
- POJ3450 Corporate Identity —— 后缀数组 最长公共子序列
题目链接:https://vjudge.net/problem/POJ-3450 Corporate Identity Time Limit: 3000MS Memory Limit: 65536 ...
随机推荐
- 安装java 和 eclipse
昨天安装eclipse出现个问题, 安装完了创建第一个项目目录的时候弹窗报错an ......什么什么, 百度一堆没有用,后来发现是jdk12不支持,换了jdk8就可以了, 然后eclipse安装py ...
- python -pickle模块、re模块学习
pickel模块 import pickle #pickle可以将任何数据类型序列化,json只能列表字典字符串数字等简单的数据类型,复杂的不可以 #但是pickle只能在python中使用,json ...
- 打印N个真值的所有真值组合
例:N=2 (true,true),(false,true),(true,false),(false,false) #include<stdio.h> int count=0; void ...
- 怎么实现hibernate悲观锁和乐观锁?
隔离级别的安全控制是整体一个大的方面,而锁机制更加的灵活,它执行的粒度可以很小,可以在一个事务中存在. Hibernate悲观锁是依靠底层数据库的锁机制实现,在查询query.setLockMode( ...
- DATAGUARD实施文档
DATAGUARD实施文档 一.前期准备及备机安装: 通过获取到的主机信息规划备机数据库安装基础信息:(注:在安装备机时需要尽量保障与主机库信息一致,以下表格中的备机信息为根据主机信息规划的安装信息. ...
- PIC32MZ 通过USB在线升级 -- USB CDC bootloader
了解bootloader 的实现,请加QQ: 1273623966 (验证填 bootloader):欢迎咨询或定制bootloader:我的博客主页www.cnblogs.com/geekygeek ...
- android开源项目之OTTO事件总线(二)官方demo解说
官方demo见 https://github.com/square/otto 注意自己该编译版本为2.3以上,默认的1.6不支持match_parent属性,导致布局文件出错. 另外需要手动添加an ...
- springmvc基础篇—使用注解方式为前台提供数据
一.新建一个Controller package cn.cfs.springmvc.service; import java.util.ArrayList; import java.util.Hash ...
- github简单使用教程(转)
github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开.对于一般人来说公共仓库就已经足够了,而且我们也没多少代码来管理,O(∩_∩)O ...
- 简单工具 & 杂技
图片压缩: 腾讯智图(http://zhitu.isux.us/) 手机的所有尺寸大小规范: http://screensiz.es/phone 需求: 移动端宽高一致的盒子(因为移动端屏幕宽度不一样 ...