POJ 2217 (后缀数组+最长公共子串)
题目链接: http://poj.org/problem?id=2217
题目大意: 求两个串的最长公共子串,注意子串是连续的,而子序列可以不连续。
解题思路:
后缀数组解法是这类问题的模板解法。
对于n个串的最长公共子串,这要把这些串连在一起,中间用"$"这类的特殊符号分隔一下。
先求后缀数组,再求最长公共前缀,取相邻两个且属于不同串的sa的最大LCP即可。
原理就是:这样把分属两个串的LCP都跑了一遍,也就是相当于把所有子串走了一遍,
只不过走这些子串是经过层层预处理过的。
下面提供一个使用的string模板,稍微稳定点。
- #include "cstring"
- #include "cstdio"
- #include "string"
- #include "iostream"
- using namespace std;
- #define maxn 30000
- struct Suffix
- {
- int r[maxn];
- int sa[maxn],rank[maxn],height[maxn];
- int t[maxn],t2[maxn],c[maxn],n,m;
- void init(string s)
- {
- n=s.size();
- for(int i=;i<n;i++) r[i]=(int)s[i];
- m=;
- }
- int cmp(int *r,int a,int b,int l) {return r[a]==r[b]&&r[a+l]==r[b+l];}
- void build()
- {
- int i,k,p,*x=t,*y=t2;
- r[n++]=;
- for (i=; i<m; i++) c[i]=;
- for (i=; i<n; i++) c[x[i]=r[i]]++;
- for (i=; i<m; i++) c[i]+=c[i-];
- for (i=n-; i>=; i--) sa[--c[x[i]]]=i;
- for (k=,p=; k<n; k*=,m=p)
- {
- for (p=,i=n-k; i<n; i++) y[p++]=i;
- for (i=; i<n; i++) if (sa[i]>=k) y[p++]=sa[i]-k;
- for (i=; i<m; i++) c[i]=;
- for (i=; i<n; i++) c[x[y[i]]]++;
- for (i=; i<m; i++) c[i]+=c[i-];
- for (i=n-; i>=; i--) sa[--c[x[y[i]]]]=y[i];
- swap(x,y);
- p=;
- x[sa[]]=;
- for (i=; i<n; i++) x[sa[i]]=cmp(y,sa[i-],sa[i],k)?p-:p++;
- }
- n--;
- }
- void LCP()
- {
- 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 (r[i+k]==r[j+k]) k++;
- height[rank[i]]=k;
- }
- }
- int LCS(string s1,string s2)
- {
- int len=s1.size();
- s1=s1+"$"+s2;
- init(s1);
- build();
- LCP();
- int ans=;
- for(int i=;i<=n;i++)
- if((sa[i-]<len)!=(sa[i]<len)) ans=max(ans,height[i]);
- return ans;
- }
- };
- int main()
- {
- //freopen("in.txt","r",stdin);
- ios::sync_with_stdio(false);
- int T;
- string s,t;
- cin>>T;getline(cin,s);
- while(T--)
- {
- getline(cin,s);
- getline(cin,t);
- Suffix a;
- cout<<"Nejdelsi spolecny retezec ma delku "<<a.LCS(s,t)<<"."<<endl;
- }
- }
13557348 | neopenx | 2217 | Accepted | 1060K | 32MS | C++ | 2109B | 2014-10-23 10:35:07 |
POJ 2217 (后缀数组+最长公共子串)的更多相关文章
- [poj 2274]后缀数组+最长公共子串
题目链接:http://poj.org/problem?id=2774 后缀数组真的太强大了,原本dp是O(nm)的复杂度,在这里只需要O(n+m). 做法:将两个串中间夹一个未出现过的字符接起来,然 ...
- 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 ...
随机推荐
- OpenGL顶点缓冲区对象(VBO)
转载 http://blog.csdn.net/dreamcs/article/details/7702701 创建VBO GL_ARB_vertex_buffer_object 扩展可 ...
- 异常详细信息: System.Data.SqlClient.SqlException:用户 'IIS APPPOOL\DefaultAppPool' 登录失败解决办法
1.安全性---登录名---新建登录名 2.常规----搜索 3.添加SERVICE用户-- 4.服务器角色---勾上sysadmin: IIS中: 应用程序池---对应的程序池上右键---高级设置 ...
- Linux netstat详解
做计算机管理员,我们都必要了解一下netstat这个命令,它是一个查看网络连接状态的工具,在windows下也默认有这个工具.Netstat命令详解 netstat命令怎样使用 如何关闭TIME_WA ...
- Java 7 的7个新特性
1.对集合类的语言支持:(??) 2.自动资源管理: 3.改进的通用实例创建类型推断:(??) 4.数字字面量下划线支持:(√) 5.switch中使用string:(√) 6.二进制字面量:(√) ...
- 【转】maven命令背后是如何工作的
转载自:http://yinny.iteye.com/blog/1883488 Maven强大的一个重要的原因是它有一个十分完善的生命周期模型(lifecycle),它有三套相互独立的生命周期,请注意 ...
- codeforces B. Vasya and Public Transport 解题报告
题目链接:http://codeforces.com/problemset/problem/355/B 题目意思:给出四种票种,c1: 某一部bus或者trolley的单程票(暗含只可以乘坐一次):c ...
- HDU 1023 Traning Problem (2) 高精度卡特兰数
Train Problem II Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u Sub ...
- Markdown 语法速查表
Markdown 语法速查表 1 标题与文字格式 标题 # 这是 H1 <一级标题> ## 这是 H2 <二级标题> ###### 这是 H6 <六级标题> 文 ...
- ShareSDK集成微信、QQ、微博分享
1.前言 为什么要使用第三方的作为集成分享的工具呢?而不去用官方的呢?有什么区别么? 一个字"快",如果你使用官方的得一个个集成他们的SDK,相信这是一个痛苦的过程. 2.准备需要 ...
- 一个非常简单的返回局部字符数组的C语言程序, 请问其输出结果?
以下是该无聊的程序: #include <stdio.h> #include <string.h> char* get_str() { int x[10]; c ...