spoj Longest Common Substring (多串求最大公共子序列)
Posted carcar
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spoj Longest Common Substring (多串求最大公共子序列)相关的知识,希望对你有一定的参考价值。
题目链接:
https://vjudge.net/problem/SPOJ-LCS
题意:
最多10行字符串
求最大公共子序列
数据范围:
$1\leq |S| \leq100000$
分析:
让他们都和第一个字符串匹配,算出每个字符串与第一个字符串的,以$i$位置(i指的是在s1中的位置)结尾匹配的最大长度
与其它字符串的匹配取最小值
最后对所有位置取最大值
超时代码:(题限是236ms,这个代码跑2000ms没问题)
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=500000*2+7; char S[maxn]; char S1[maxn/2]; int ans[maxn/2]; int n,a,b,len1,len2; struct suffixautomation int mp[maxn*2][30],fa[maxn*2],ed,ct,len[maxn*2],minpos[maxn*2],maxpos[maxn*2],deg[maxn*2]; int res[maxn/2]; suffixautomation() for(int i=0;i<maxn*2;i++)minpos[i]=1e9,maxpos[i]=-1; ed=ct=1; inline void ins(int c,int pos) int p=ed;ed=++ct;minpos[ed]=maxpos[ed]=pos;len[ed]=pos;//先初始化size和len for(;p&&mp[p][c]==0;p=fa[p])mp[p][c]=ed;//然后顺着parent树的路径向上找 if(p==0)fa[ed]=1;return;int q=mp[p][c];//case1 if(len[p]+1==len[q])fa[ed]=q;return;//case2 len[++ct]=len[p]+1;//case 3 for(int i=1;i<=26;i++)mp[ct][i]=mp[q][i]; fa[ct]=fa[q];fa[q]=ct;fa[ed]=ct; for(int i=p;mp[i][c]==q;i=fa[i])mp[i][c]=ct; void solve() for(int i=1;i<=ct;i++)deg[fa[i]]++; queue<int>que; for(int i=1;i<=ct;i++)if(deg[i]==0)que.push(i); while(que.size()) int x=que.front(); int y=fa[x]; que.pop(); minpos[y]=min(minpos[x],minpos[y]); maxpos[y]=max(maxpos[x],maxpos[y]); deg[y]--; if(deg[y]==0)que.push(y); for(int i=1;i<=ct;i++) if(minpos[i]<=len1&&maxpos[i]>=len1+2) res[minpos[i]]=max(res[minpos[i]],len[i]); sam,sam2; int main() // cout<<"acfvd" for(int i=0;i<maxn/2;i++)ans[i]=1e9; scanf("%s",S+1); len1=strlen(S+1); S[len1+1]=‘z‘+1; while(scanf("%s",S1+1)==1) len2=strlen(S1+1); sam=sam2; for(int i=len1+2;i<=len1+len2+1;i++) S[i]=S1[i-len1-1]; for(int i=1;i<=len1+len2+1;i++)sam.ins(S[i]-‘a‘+1,i); sam.solve(); for(int i=1;i<=len1;i++) ans[i]=min(ans[i],sam.res[i]); int res=0; for(int i=1;i<=len1;i++) if(ans[i]!=1e9)res=max(res,ans[i]); printf("%d\n",res); return 0;
以上是关于spoj Longest Common Substring (多串求最大公共子序列)的主要内容,如果未能解决你的问题,请参考以下文章
刷题SPOJ 1811 LCS - Longest Common Substring
SPOJ 1811 Longest Common Substring
Spoj LCS2 - Longest Common Substring II
spoj1812 LCS2 - Longest Common Substring II