并不对劲的spoj1812
题意是求多个串的lcs。
这也是道后缀自动机的模板题。对于任意一个字符串建后缀自动机,用其他串查询就行。对于后缀自动机的每个状态要额外记匹配到当前状态的最大长度。
和spoj1811的区别在于这道题不方便后缀数组做。当然,如果不嫌很多个串用奇怪的字符连起来麻烦、判断时常数极大的话,也可以试试。 字符串总数不多,好像还真行。
#include<iostream> #include<iomanip> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #define maxn 100010 using namespace std; int ans,len,p; int read(){ int f=1,x=0;char ch=getchar(); while(isdigit(ch)==0 && ch!='-')ch=getchar(); if(ch=='-')f=-1,ch=getchar(); while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } void write(int x){ int ff=0;char ch[15]; while(x)ch[++ff]=(x%10)+'0',x/=10; if(ff==0)putchar('0'); while(ff)putchar(ch[ff--]); putchar(' '); } typedef struct node{ int to[30],dis,fa; }spot; struct SAM{ spot x[maxn*2]; int ls,ls2,q,cnt,rt,lst,c[maxn*2],ord[maxn*2],ans[maxn*2],maxl[maxn*2]; char s[maxn]; void start(){ lst=rt=++cnt; scanf("%s",s+1); ls=strlen(s+1); for(int i=1;i<=ls;i++) extend(i); for(int i=1;i<=cnt;i++) ans[i]=x[i].dis; } void extend(int pos){ int val=s[pos]-'a',p=lst,np=++cnt; lst=np,x[np].dis=pos; for(;p&&x[p].to[val]==0;p=x[p].fa)x[p].to[val]=np; if(p==0)x[np].fa=rt; else{ int q=x[p].to[val]; if(x[q].dis==x[p].dis+1)x[np].fa=q; else{ int nq=++cnt; x[nq].dis=x[p].dis+1; memcpy(x[nq].to,x[q].to,sizeof(x[q].to)); x[nq].fa=x[q].fa,x[np].fa=x[q].fa=nq; for(;x[p].to[val]==q;p=x[p].fa)x[p].to[val]=nq; } } } void qsort(){ for(int i=1;i<=cnt;i++) c[x[i].dis]++; for(int i=1;i<=ls;i++) c[i]+=c[i-1]; for(int i=1;i<=cnt;i++) ord[c[x[i].dis]--]=i; } int work(){ while(scanf("%s",s+1)!=EOF){ len=0; memset(maxl,0,sizeof(maxl)); ls2=strlen(s+1); for(int i=1;i<=ls2;i++){ int val=s[i]-'a'; if(x[p].to[val])len++,p=x[p].to[val]; else{ for(;p&&x[p].to[val]==0;p=x[p].fa); if(p==0)p=rt,len=0; else len=x[p].dis+1,p=x[p].to[val]; } maxl[p]=max(maxl[p],len); } for(int i=cnt;i>=1;i--){ int u=ord[i]; ans[u]=min(ans[u],maxl[u]); if(x[u].fa && maxl[u])maxl[x[u].fa]=x[x[u].fa].dis; } } int res=0; for(int i=1;i<=cnt;i++){ res=max(res,ans[i]); } return res; } }t; int main(){ t.start(); t.qsort(); int res=t.work(); write(res); return 0; }