SP1811 LCS

题目链接:SP1811 LCS


对串A建立SAM,计算每一个b字符结尾的答案。

对于当前字符有向下的转移就直接 len++,跳过去。
否则一直向上跳父亲。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e6+10;
char a[N],b[N];	int na,nb;
struct SAM{
	int cnt=1,last=1;
	struct node{int ch[26],len,fa;}d[N];
	inline void insert(int c){
		int p=last,np=last=++cnt;	d[np].len=d[p].len+1;
		for(;p&&!d[p].ch[c];p=d[p].fa)	d[p].ch[c]=np;
		if(!p)	d[np].fa=1;
		else{
			int q=d[p].ch[c];
			if(d[q].len==d[p].len+1)	d[np].fa=q;
			else{
				int nq=++cnt;
				d[nq]=d[q],d[nq].len=d[p].len+1,d[q].fa=d[np].fa=nq;
				for(;p&&d[p].ch[c]==q;p=d[p].fa) d[p].ch[c]=nq;
			}
		}
	}
	inline void build(){for(int i=1;i<=na;i++)	insert(a[i]-'a');}
	void calc(){
		int p=1,res=0,len=0;
		for(int i=1;i<=nb;i++){
			int k=b[i]-'a';
			if(d[p].ch[k])	len++,p=d[p].ch[k];
			else{
				for(;p&&!d[p].ch[k];p=d[p].fa);
				if(p)	len=d[p].len+1,p=d[p].ch[k];
				else len=0,p=1;
			}
			res=max(res,len);
		}
		cout<<res;
	}
}sam;
signed main(){
	scanf("%s %s",a+1,b+1);	na=strlen(a+1),nb=strlen(b+1);
	sam.build();	sam.calc();
	return 0;
}
发布了809 篇原创文章 · 获赞 246 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/105195600
LCS