并不对劲的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;
}
并不对劲的lcs

 

posted @ 2018-01-19 14:38  echo6342  阅读(209)  评论(0编辑  收藏  举报