zoukankan      html  css  js  c++  java
  • 并不对劲的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
  • 相关阅读:
    显示文件本地文件夹
    Select Dependencies选择依赖项
    搜索小技巧
    783. Minimum Distance Between BST Nodes BST节点之间的最小距离
    5. Longest Palindromic Substring 最长的回文子串
    12. Integer to Roman 整数转罗马数字
    3. Longest Substring Without Repeating Characters 最长的子串不重复字符
    539. Minimum Time Difference 最小时差
    43. Multiply Strings 字符串相乘
    445. Add Two Numbers II 两个数字相加2
  • 原文地址:https://www.cnblogs.com/xzyf/p/8275970.html
Copyright © 2011-2022 走看看