zoukankan      html  css  js  c++  java
  • POJ3294Life Forms(广义后缀自动机)(后缀数组+二分+数状数组)

    You may have wondered why most extraterrestrial life forms resemble humans, differing by superficial traits such as height, colour, wrinkles, ears, eyebrows and the like. A few bear no human resemblance; these typically have geometric or amorphous shapes like cubes, oil slicks or clouds of dust.

    The answer is given in the 146th episode of Star Trek - The Next Generation, titled The Chase. It turns out that in the vast majority of the quadrant's life forms ended up with a large fragment of common DNA.

    Given the DNA sequences of several life forms represented as strings of letters, you are to find the longest substring that is shared by more than half of them.

    Input

    Standard input contains several test cases. Each test case begins with 1 ≤ n ≤ 100, the number of life forms. n lines follow; each contains a string of lower case letters representing the DNA sequence of a life form. Each DNA sequence contains at least one and not more than 1000 letters. A line containing 0 follows the last test case.

    Output

    For each test case, output the longest string or strings shared by more than half of the life forms. If there are many, output all of them in alphabetical order. If there is no solution with at least one letter, output "?". Leave an empty line between test cases.

    Sample Input

    3
    abcdefg
    bcdefgh
    cdefghi
    3
    xxx
    yyy
    zzz
    0

    Sample Output

    bcdefg
    cdefgh
    
    ?

    题意:

    给定一些模板字符串,求一个最长公共字串,这个最长公共字串至少在一半以上的字符串里出现过。

    思路:

    把模板字符串都连接起来。二分长度,RMQ去验证。

     (服了,网上找不到广义后缀自动机的资料。。。)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<memory>
    #include<cmath>
    #define maxn 350003
    using namespace std;
    int n,len,ans,Max,now;
    char s[1010],cap[1010];
    struct SAM
    {
        int ch[maxn][26],fa[maxn],maxlen[maxn],Last,sz;
        int root,nxt[maxn],size[maxn];
        void init()
        {
            sz=0;
            root=++sz;
            memset(size,0,sizeof(size));
            memset(ch[1],0,sizeof(ch[1]));
            memset(nxt,0,sizeof(nxt));
        }
        void add(int x)
        {
            int np=++sz,p=Last;Last=np;
            memset(ch[np],0,sizeof(ch[np]));
            maxlen[np]=maxlen[p]+1;
            while(p&&!ch[p][x]) ch[p][x]=np,p=fa[p];
            if(!p) fa[np]=1;
            else {
                int q=ch[p][x];
                if(maxlen[p]+1==maxlen[q]) fa[np]=q;
                else {
                    int nq=++sz;
                    memcpy(ch[nq],ch[q],sizeof(ch[q]));size[nq]=size[q]; nxt[nq]=nxt[q];
                    maxlen[nq]=maxlen[p]+1;
                    fa[nq]=fa[q];
                    fa[q]=fa[np]=nq;
                    while(p&&ch[p][x]==q) ch[p][x]=nq,p=fa[p];
                }
            }
            for(;np;np=fa[np]) 
              if(nxt[np]!=now) {
                  size[np]++;
                  nxt[np]=now;
              }else break;
        }
        void dfs(int x,int d){//输出    
           if(d!=maxlen[x] || d>ans) return;
           if(maxlen[x]==ans && size[x]>n){ puts(cap); return; }
              for(int i=0;i<26;++i)
              if(ch[x][i]){ cap[d]=i+'a'; dfs(ch[x][i],d+1); cap[d]=0; }
        }
    };
    SAM Sam;
    int main()
    {
        while(~scanf("%d",&n)&&n){     
            Sam.init();
            for(int i=1;i<=n;i++) {
                scanf("%s",s+1);
                Sam.Last=Sam.root;
                len=strlen(s+1);
                now=i;
                for(int j=1;j<=len;j++) Sam.add(s[j]-'a');
            }
            Max=0;ans=0;n>>=1;
            for(int i=1;i<=Sam.sz;i++) 
                if(Sam.size[i]>n&&Sam.maxlen[i]>ans) { Max=i;ans=Sam.maxlen[i];}
            if(ans) Sam.dfs(1,0);
            else puts("?");
            puts("");
        }
        return 0;
    }

    参考:http://blog.csdn.net/JacaJava/article/details/78678612?locationNum=6&fps=1

  • 相关阅读:
    CentOS初步学习记录(五)用户和用户组
    CentOS初步学习记录(四)curl文件传输和grep文本搜索
    微信公众号推文svg点击交互的方法
    layaair写动画的方法 用时间轴最方便
    spring boot 整合Elasticsearch
    java spring boot 拦截器 实现未登录用户不能登录
    java win 安装 activemq教程
    java spring boot Swagger2 构建api文档
    java spring boot @bean的用法
    java spring boot 写入日志
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8024237.html
Copyright © 2011-2022 走看看