POJ 2774 Long Long Message ——后缀数组
【题目分析】
用height数组RMQ的性质去求最长的公共子串。
要求sa[i]和sa[i-1]必须在两个串中,然后取height的MAX。
利用中间的字符来连接两个字符串的思想很巧妙,记得最后还需要空一个位置避免冲突。
【代码】
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 200005
#define inf 0x3f3f3f3f
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
void Finout()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
}
int Getint()
{
int x=0,f=1; char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int tot=0,l1,l2;
char s1[maxn],s2[maxn];
struct Suf_Arr{
int s[maxn<<1],l;
int wa[maxn],wb[maxn],wv[maxn],ws[maxn];
int sa[maxn],rank[maxn],height[maxn];
int cmp(int *r,int a,int b,int l)
{return r[a]==r[b]&&r[a+l]==r[b+l];}
void getsa(int n,int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for (i=0;i<m;++i) ws[i]=0;
for (i=0;i<n;++i) ws[x[i]=s[i]]++;
for (i=1;i<m;++i) ws[i]+=ws[i-1];
for (i=n-1;i>=0;--i) sa[--ws[x[i]]]=i;
for (j=1,p=1;p<n;j*=2,m=p)
{
for (p=0,i=n-j;i<n;++i) y[p++]=i;
for (i=0;i<n;++i) if (sa[i]>=j) y[p++]=sa[i]-j;
for (i=0;i<n;++i) wv[i]=x[y[i]];
for (i=0;i<m;++i) ws[i]=0;
for (i=0;i<n;++i) ws[wv[i]]++;
for (i=1;i<m;++i) ws[i]+=ws[i-1];
for (i=n-1;i>=0;--i) sa[--ws[wv[i]]]=y[i];
for (t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;++i)
x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
}
}
void gethi(int n)
{
int i,j,k=0;
for (i=1;i<=n;++i) rank[sa[i]]=i;
for (int i=0;i<n;height[rank[i++]]=k)
for (k?k--:0,j=sa[rank[i]-1];s[i+k]==s[j+k];k++);
}
void build()
{
getsa(l+2,30);
// for (int i=0;i<=l;++i) cout<<sa[i]<<" "; cout<<endl;
gethi(l+1);
}
void solve()
{
int maxx=0;
for(int i=2;i<l;++i)
if (height[i]>maxx)
{
if (0<=sa[i-1]&&sa[i-1]<l1&&l1<sa[i]) maxx=height[i];
if (0<=sa[i]&&sa[i]<l1&&l1<sa[i-1]) maxx=height[i];
}
printf("%d\n",maxx);
}
}arr;
int main()
{
Finout();
scanf("%s",s1); scanf("%s",s2);
l1=strlen(s1); l2=strlen(s2); arr.l=l1+l2+1;
for (int i=0;i<l1;++i) arr.s[i]=s1[i]-'a'+1;
for (int i=0;i<l2;++i) arr.s[i+l1+1]=s2[i]-'a'+1;
arr.s[l1+l2+1]=0; arr.s[l1]=28;
// printf("len is %d\n",arr.l);
// for (int i=0;i<=arr.l;++i) cout<<(char)(arr.s[i]+'a'-1); cout<<endl;
arr.build();
arr.solve();
}
POJ 2774 Long Long Message ——后缀数组的更多相关文章
- POJ 2774 Long Long Message 后缀数组
Long Long Message Description The little cat is majoring in physics in the capital of Byterland. A ...
- poj 2774 Long Long Message 后缀数组基础题
Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 24756 Accepted: 10130 Case Time Limi ...
- poj 2774 Long Long Message 后缀数组LCP理解
题目链接 题意:给两个长度不超过1e5的字符串,问两个字符串的连续公共子串最大长度为多少? 思路:两个字符串连接之后直接后缀数组+LCP,在height中找出max同时满足一左一右即可: #inclu ...
- POJ 2774 Long Long Message 后缀数组模板题
题意 给定字符串A.B,求其最长公共子串 后缀数组模板题,求出height数组,判断sa[i]与sa[i-1]是否分属字符串A.B,统计答案即可. #include <cstdio> #i ...
- POJ 2774 Long Long Message (后缀数组+二分)
题目大意:求两个字符串的最长公共子串长度 把两个串接在一起,中间放一个#,然后求出height 接下来还是老套路,二分出一个答案ans,然后去验证,如果有连续几个位置的h[i]>=ans,且存在 ...
- POJ - 2774 Long Long Message (后缀数组/后缀自动机模板题)
后缀数组: #include<cstdio> #include<algorithm> #include<cstring> #include<vector> ...
- PKU 2774 Long Long Message (后缀数组练习模板题)
题意:给你两个字符串.求最长公共字串的长度. by:罗穗骞模板 #include <iostream> #include <stdio.h> #include <stri ...
- 后缀数组(模板题) - 求最长公共子串 - poj 2774 Long Long Message
Language: Default Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 21 ...
- [POJ 2774] Long Long Message 【后缀数组】
题目链接:POJ - 2774 题目分析 题目要求求出两个字符串的最长公共子串,使用后缀数组求解会十分容易. 将两个字符串用特殊字符隔开再连接到一起,求出后缀数组. 可以看出,最长公共子串就是两个字符 ...
随机推荐
- Java ClassLoader 原理详细分析(转)
转载自:http://www.codeceo.com/article/java-classloader.html 一.什么是ClassLoader? 大家都知道,当我们写好一个Java程序之后,不是管 ...
- NOSDK--一键打包的实现(五)
1.5 mac下的脚本环境配置及脚本的使用 脚本环境主要依赖sdk,ndk和ant,前两个可以在android官方网站下载(被墙了的话只能FQ了). android-sdk-macosx androi ...
- Linux vmstat使用
Vmstat命令的简单使用 Vmstat命令是Linux/unix常用的系统监控工具,可以方便的查看CPU.内存.swap分区.IO读写等情况. Vmstat常用的参数主要有两个:1.采集的时间间隔 ...
- 使用Grunt构建自动化开发环境
1.准备工作 1)首页确保电脑上网,以及能够访问https://registry.npmjs.org/,因需从此网站中下载安装相应的插件; 2)电脑安装Node.js,Grunt及Grunt插件都是基 ...
- Handler sendMessage 与 obtainMessage (sendToTarget)比较
转自:http://iaiai.iteye.com/blog/1992196 obtainmessage()是从消息池中拿来一个msg 不需要另开辟空间new new需要重新申请,效率低,obtian ...
- 利用SQLite_Expert实现Excel表转SqLite数据库
1.保留excel数据中需要的字段,删除无关字段. 2.将excel另存为cvs格式文件.<另存名称如:jizhan.cvs 则导入后表名即为jizhan> 3.看下图,新建数据库,命名为 ...
- 总结初用erlang 时的遇到一些问题
算起来接触erlang 三个多月快四个月来,期间从零开始看书写erlang代码.修改RabbitMQ.业务开发.系统调优,总算是有点入门了. 最难受的是边学边修改RabbitMQ,开始真心的看不懂,不 ...
- hibernate id 策略
@Id@GeneratedValue(generator = "paymentableGenerator")@GenericGenerator(name = "payme ...
- VC++ GetModuleFileName()获取路径字符串中带波浪线~
GetModuleFileName()获取的字符串中带波浪线,不是完整的路径显示. 原因:获取的是短路径,进行了缩写 解决:还原长路径 TCHAR }; GetLongPathName( strTem ...
- yii框架安装
YII安装: 下载最版本http://www.framework.com 下载高级的->yii with advanced APPlication template 解压至访问目录下 ...