SPOJ-LCS 后缀自动机
Posted mountaink
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ-LCS 后缀自动机相关的知识,希望对你有一定的参考价值。
题意:给出两个$n=250000$的字符串,求最长公共子串。
思路:把第一个字符串放到SAM里面去。
对于第二个串,能匹配则匹配,不能匹配就跳回能匹配的位置,如果一个都不能匹配,则cur要重新初始化为root。
对后缀自动机的理解还比较模糊,怕误人子弟,此题就不做详述。
#include<bits/stdc++.h> #define clr(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; const int maxn=250010*2; char s1[maxn],s2[maxn]; int len1,len2,len[maxn],tot=1,root=1,last=1,ch[maxn][27],fa[maxn]; void extend(int x){ int now=++tot,pre=last; last=now,len[now]=len[pre]+1; while( pre && !ch[pre][x]){ ch[pre][x]=now; pre=fa[pre]; } if(!pre)fa[now]=root; else{ int q = ch[pre][x]; if(len[q]==len[pre]+1)fa[now]=q; else{ int nows = ++tot; memcpy(ch[nows],ch[q],sizeof(ch[q])); len[nows]=len[pre]+1; fa[nows]=fa[q]; fa[q]=fa[now]=nows; for(;pre && ch[pre][x] == q;pre=fa[pre]){ ch[pre][x]=nows; } } } } int main(){ scanf("%s",s1); scanf("%s",s2); len1=strlen(s1); len2=strlen(s2); for(int i=0;i<len1;i++) { int p=s1[i]-‘a‘; extend(p); } int maxx=0,cur=root,ans=0; for(int i=0;i<len2;i++,ans=max(maxx,ans)) { int p=s2[i]-‘a‘; if(ch[cur][p]){ cur=ch[cur][p]; maxx++; continue; } while(cur&&ch[cur][p]==0){ cur=fa[cur]; } if(cur){ maxx=len[cur]+1; cur=ch[cur][p]; }else{ cur=1; maxx=0; } } printf("%d ",ans); }
以上是关于SPOJ-LCS 后缀自动机的主要内容,如果未能解决你的问题,请参考以下文章
[SPOJ-LCS]Longest Common Substring
Codeforces 86C Genetic engineering(AC自动机+DP)
我的Android进阶之旅关于Android平台获取文件的mime类型:为啥不传小写后缀名就获取不到mimeType?为啥android 4.4系统获取不到webp格式的mimeType呢?(代码片段
我的Android进阶之旅关于Android平台获取文件的mime类型:为啥不传小写后缀名就获取不到mimeType?为啥android 4.4系统获取不到webp格式的mimeType呢?(代码片段