SPOJ 1811 Longest Common Substring

Posted 北屿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ 1811 Longest Common Substring相关的知识,希望对你有一定的参考价值。

Description

给出两个字符串,求最长公共子串.

Sol

SAM.

这题随便做啊...后缀数组/Hash+二分都可以.

SAM就是模板啊...直接在SAM上跑就行,没有了 \(go[w]\) 就往 \(par\) 跳.

每走一步统计一下答案.

Code

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

const int N = 250005;

struct State{
	State *par,*go[26];
	int val;
	State(int _val):par(0),val(_val){ memset(go,0,sizeof(go)); }
}*rt,*lst;
void extend(int w){
	State *p=lst,*np=new State(p->val+1);
	while(p && p->go[w]==0) p->go[w]=np,p=p->par;
	if(!p) np->par=rt;
	else{
		State *q=p->go[w];
		if(q->val == p->val+1) np->par=q;
		else{
			State *nq=new State(p->val+1);
			memcpy(nq->go,q->go,sizeof(q->go));
			nq->par=q->par;
			np->par=q->par=nq;
			while(p && p->go[w] == q) p->go[w]=nq,p=p->par;
		}
	}lst=np;
}

char A[N],B[N];
int la,lb,ans,len;

void work(){
	State *t=rt;
	for(int i=0;i<lb;i++){
		for(;t && !t->go[B[i]-‘a‘];len=(t=t->par) ? t->val : 0);
		if(t && t->go[B[i]-‘a‘]) t=t->go[B[i]-‘a‘],len++;else t=rt;
		ans=max(ans,len);
	}
}
int main(){
	rt=new State(0),lst=rt;
	
	scanf("%s%s",A,B);
	la=strlen(A),lb=strlen(B);
	
	for(int i=0;i<la;i++) extend(A[i]-‘a‘);
	
	work();
	return cout<<ans<<endl,0;
}

  

以上是关于SPOJ 1811 Longest Common Substring的主要内容,如果未能解决你的问题,请参考以下文章

SPOJ 1811 Longest Common Substring

●SPOJ 1811 Longest Common Substring

SPOJ 1811 Longest Common Substring(求两个串的最长公共子串)

spoj 1812 LCS2 - Longest Common Substring II (后缀自己主动机)

[SPOJ1812]Longest Common Substring II

SPOJ1812 Longest Common Substring II