SPOJ1811 LCS - Longest Common Substring (SA)

题目链接

一道好题啊!
QWQ
性质可以直接参考的我的后缀数组学习笔记!

首先,两个串的题,第一反应肯必定是把两个串接起来,然后中间加入一个非法字符。

那么实际上我们就是求一个最大的 l c p lcp 满足一端属于A,另一端属于 B B

直接对符合要求的 h e i g h t height 求个 m a x max 就可以了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk make_pair
#define ll long long
using namespace std;
inline int read()
{
  int x=0,f=1;char ch=getchar();
  while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
  while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  return x*f;
}
const int maxn = 2e6+1e2;
int wb[maxn],sa[maxn],rk[maxn];
int n,m;
char a[maxn];
int tmp[maxn];
int h[maxn],height[maxn];
char s[maxn],s1[maxn];
int len,len1;
void getsa()
{
	int *x=rk,*y=tmp;
	int s=128;
	int p=0;
	for (int i=1;i<=n;i++) x[i]=a[i],y[i]=i;
	for (int i=1;i<=s;i++) wb[i]=0;
	for (int i=1;i<=n;i++) wb[x[y[i]]]++;
	for (int i=1;i<=s;i++) wb[i]+=wb[i-1];
	for (int i=n;i>=1;i--) sa[wb[x[y[i]]]--]=y[i];
	for (int j=1;p<n;j<<=1)
	{
		p=0;
		for (int i=n-j+1;i<=n;i++) y[++p]=i;
		for (int i=1;i<=n;i++) if (sa[i]>j) y[++p]=sa[i]-j;
		for (int i=1;i<=s;i++) wb[i]=0;
		for (int i=1;i<=n;i++) wb[x[y[i]]]++;
		for (int i=1;i<=s;i++) wb[i]+=wb[i-1];
		for (int i=n;i>=1;i--) sa[wb[x[y[i]]]--]=y[i];
		swap(x,y);
		p=1;
		x[sa[1]]=1;
	    for (int i=2;i<=n;i++)
	    {
	    	x[sa[i]]=(y[sa[i]]==y[sa[i-1]] && y[sa[i]+j]==y[sa[i-1]+j]) ? p : ++p;
		}
		s=p;
	} 
	for (int i=1;i<=n;i++) rk[sa[i]]=i;
	h[0]=0;
	for(int i=1;i<=n;i++)
	{
		h[i]=max(h[i-1]-1,0);
		while (i+h[i]<=n && sa[rk[i]-1]+h[i]<=n && a[i+h[i]]==a[sa[rk[i]-1]+h[i]]) h[i]++;
	}
	for (int i=1;i<=n;i++) height[i]=h[sa[i]];
} 
int main()
{
  scanf("%s",s+1);
  scanf("%s",s1+1);
  len = strlen(s+1);
  len1 = strlen(s1+1);
  for (int i=1;i<=len;i++) a[++n]=s[i];
  a[++n]='*';
  for (int i=1;i<=len1;i++) a[++n]=s1[i];
  getsa();
  int ans=0;
  for (int i=2;i<=n;i++)
  {
  	if (sa[i]<=len && sa[i-1]>len+1)
  	{
  		ans=max(ans,height[i]);
	}
	else
	{
		if (sa[i]>len+1 && sa[i-1]<=len)
		{
			ans=max(ans,height[i]);
		}
	}
  } 
  cout<<ans;
  return 0;
}

猜你喜欢

转载自blog.csdn.net/y752742355/article/details/84991496