【题目分析】

用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. Java Web ——http协议响应报文

    HTTP 响应报文 HTTP 响应报文由状态行.响应头部.空行 和 响应包体 4 个部分组成,如下图所示: 下面对响应报文格式进行简单的分析: 状态行:状态行由 HTTP 协议版本字段.状态码和状态码 ...

  2. Java开源库

    Java SE 7 API Docs from Oracle Apache IO库操作IO与文件 2.4 XML4j 1.6.1 Json.org google-json 2.5 WindowBuil ...

  3. telnet 传输文件

    用python创建个临时服务器,发送文件供telnet访问 import socket import base64 port = 10005 filename = 'libcrypto.so.1.0. ...

  4. webstorm ES6 转 ES5

    一句话总结:用WebStorm自带的File Watcher功能+Babel实现自动转换ECMAScript 6代码为ES5代码 1. 新建一个Empty Project,然后在src目录下新建了一个 ...

  5. EventBus

    EventBus GitHub 上的地址 https://github.com/greenrobot/EventBus EventBus干的事情可以概括来说 别人可以根据某一个事件订阅我,但是他得去实 ...

  6. MySQL 磁盘I/O问题

    一.使用磁盘阵列:RAID,廉价磁盘冗余阵列,可靠性,性能好. 二.使用 Symbolic Links 分布I/O 利用操作系统的符号链接将不同的数据库或表.索引指向不同的物理磁盘,达到分布磁盘I/O ...

  7. svn post-commit 同步

    @echo on SET REPOS=%1 SET USER=%2 SET SVN="D:\Program Files\VisualSVN Server\bin\svn.exe" ...

  8. 微软KinectV2深度传感器在Ubuntu上的配置和使用

    最新博客地址已转到: http://blog.csdn.net/zzlyw?viewmode=contents   ------------------------------------------ ...

  9. 使用 Git Hooks 实现自动项目部署

    最近在某服务器上面搭建 git 开发和部署环境,git 开发环境很简单,按照 ProGit 一书的相关知识就可以轻松搞定,实现了类似 Github 的使用 SSH + 私有 Clone 的方式. 关于 ...

  10. Content-disposition

    今天查看Struts2的文件上传部分 发现有个例子开头打印的信息中有Content-Disposition,一时好奇,所以了解了一下.顺便学习一下文件上传所需要的注意事项. Content-dispo ...