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
  • 相关阅读:
    Kbuild文件
    patch与diff的恩怨
    依据linux Oops信息准确定位错误代码所在行
    理解嵌入式开发中的一些硬件相关的概念
    linux内核中经常用到的设备初始化宏
    如何实例化i2c_client(四法)
    设计和编写设备驱动的一般方法
    [转] rtp h264注意点(FU-A分包方式说明)
    c语言的label后面不能直接跟变量申明
    互联网目前最有影响力的流量统计网站
  • 原文地址:https://www.cnblogs.com/xzyf/p/8275970.html
Copyright © 2011-2022 走看看