【题目分析】

用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 ——后缀数组的更多相关文章

  1. POJ 2774 Long Long Message 后缀数组

    Long Long Message   Description The little cat is majoring in physics in the capital of Byterland. A ...

  2. poj 2774 Long Long Message 后缀数组基础题

    Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 24756   Accepted: 10130 Case Time Limi ...

  3. poj 2774 Long Long Message 后缀数组LCP理解

    题目链接 题意:给两个长度不超过1e5的字符串,问两个字符串的连续公共子串最大长度为多少? 思路:两个字符串连接之后直接后缀数组+LCP,在height中找出max同时满足一左一右即可: #inclu ...

  4. POJ 2774 Long Long Message 后缀数组模板题

    题意 给定字符串A.B,求其最长公共子串 后缀数组模板题,求出height数组,判断sa[i]与sa[i-1]是否分属字符串A.B,统计答案即可. #include <cstdio> #i ...

  5. POJ 2774 Long Long Message (后缀数组+二分)

    题目大意:求两个字符串的最长公共子串长度 把两个串接在一起,中间放一个#,然后求出height 接下来还是老套路,二分出一个答案ans,然后去验证,如果有连续几个位置的h[i]>=ans,且存在 ...

  6. POJ - 2774 Long Long Message (后缀数组/后缀自动机模板题)

    后缀数组: #include<cstdio> #include<algorithm> #include<cstring> #include<vector> ...

  7. PKU 2774 Long Long Message (后缀数组练习模板题)

    题意:给你两个字符串.求最长公共字串的长度. by:罗穗骞模板 #include <iostream> #include <stdio.h> #include <stri ...

  8. 后缀数组(模板题) - 求最长公共子串 - poj 2774 Long Long Message

    Language: Default Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 21 ...

  9. [POJ 2774] Long Long Message 【后缀数组】

    题目链接:POJ - 2774 题目分析 题目要求求出两个字符串的最长公共子串,使用后缀数组求解会十分容易. 将两个字符串用特殊字符隔开再连接到一起,求出后缀数组. 可以看出,最长公共子串就是两个字符 ...

随机推荐

  1. Linux C--信号 sigaction函数

    使用 sigaction 函数: signal 函数的使用方法简单,但并不属于 POSIX 标准,在各类 UNIX 平台上的实现不尽相同,因此其用途受 到了一定的限制.而 POSIX 标准定义的信号处 ...

  2. mac 快捷键拾遗

    1.隐藏所有其它窗口 (hide) 窗口太多太乱,按下Command+Option/alt+H组合键,除了当前窗口以外的其它窗口会自动隐藏(不是缩小). 2. Command X        留意, ...

  3. Code Snippets 代码片段

    Code Snippets 代码片段       1.Title : 代码片段的标题 2.Summary : 代码片段的描述文字 3.Platform : 可以使用代码片段的平台,有IOS/OS X/ ...

  4. HTML 内容居中方式总结

    在HTML网页排版经常会用到关于对其方式的情况,水平居中和垂直居中.特别是水平居中,并不是一个简单的text-align就可以解决所有的情况. 开始之前普及一点HTML知识,目标很明显,不同的页面结构 ...

  5. OSI7层模型详解

    首先我们借用百度百科上的图片来基本了解一下OSI7层模型的名称以及结构.下面我将从最底层一层一层往上介绍. 物理层:基于Bit传输,是属于物理信道,最基本的机械.电子.定时接口通信信道. 数据链路层: ...

  6. Rails sanitize

    The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements. T ...

  7. 泛型DAO与泛型Service

    泛型Dao与Service 看了几个帖子,泛型Dao与Service的主要目的就是要减少重复代码.具体的说明如下: 1. 定义一个BaseDao接口,此接口包含了一些通用的DAO操作,例如:增加.删除 ...

  8. pip安装报错:is not a supported wheel on this platform

    可能的原因1:安装的不是对应python版本的库,下载的库名中cp27代表python2.7,其它同理. 可能的原因2:这个是我遇到的情况(下载的是对应版本的库,然后仍然提示不支持当前平台) 我下载到 ...

  9. APUE学习--第三版apue编译

    第三版apue编译:     1. 首先在  http://www.apuebook.com/   下载源码解压:      tar zxvf src.3e.tar.gz 看完Readme可知,直接执 ...

  10. zabbix安装unixODBC配置完之后报错

    zabbix安装unixODBC配置完之后报错 libmysqlclient_16 not defined in file libmysqlclient_r.so.16 分析 我没有使用centos6 ...