zoukankan      html  css  js  c++  java
  • Mr. Panda and Fantastic Beasts

    F - Mr. Panda and Fantastic Beasts

    参考:[acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Fantastic Beasts 后缀自动机

    把2~n的串用一个特殊字符串起来,然后对这个新串建后缀自动机,然后用第一个串在这个自动机上进行匹配即可,当失配的时候就跟答案进行比较,取最优解。le=len[link[now]]+1的意思是让 le 的值为当前节点所表示字符串的最短长度。

    // Created by CAD
    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn=2e5+5e4+5;
    namespace sam{
        int len[maxn<<1],link[maxn<<1],Next[maxn<<1][30];
        int sz,last;
        string ans="",s;
        void init(){                //记得初始化
            for(int i=0;i<=sz;++i){
                len[i]=link[i]=0;
                for(int j=0;j<=26;++j)
                    Next[i][j]=0;
            }
            sz=last=0;
            len[0]=0,link[0]=-1;
    
        }
        void insert(char c){        //插入字符
            int now=++sz;
            len[now]=len[last]+1;
            int p=last;
            while(~p&&!Next[p][c-'a']){
                Next[p][c-'a']=now;
                p=link[p];
            }
            if(p==-1) link[now]=0;
            else{
                int q=Next[p][c-'a'];
                if(len[p]+1==len[q]) link[now]=q;
                else{
                    int clone=++sz;
                    len[clone]=len[p]+1;
                    memcpy(Next[clone],Next[q],sizeof(Next[q]));
                    link[clone]=link[q];
                    while(~p&&Next[p][c-'a']==q){
                        Next[p][c-'a']=clone;
                        p=link[p];
                    }
                    link[q]=link[now]=clone;
                }
            }
            last=now;
        }
        void update(int l,int r){
            if(ans.length()>r-l+1||ans=="") ans=s.substr(l,r-l+1);
            else if(ans.length()<r-l+1) return ;
            else if(ans>s.substr(l,r-l+1))
                ans=s.substr(l,r-l+1);
        }
        int now=0,le=0;
        void attempt(char x,int op){
            x-='a';
            if(Next[now][x])
                now=Next[now][x],le=len[link[now]]+1;
            else{
                while(~now&&!Next[now][x]){
                    update(op-le,op);
                    now=link[now];
                    if(~now)    le=len[link[now]]+1;
                }
                if(now==-1) now=0,le=0;
                else now=Next[now][x],le=len[link[now]]+1;
            }
        }
        void solve(){
            ans="";
            now=le=0;
            for(int i=0;i<s.length();++i)
                attempt(s[i],i);
        }
    }
    
    int main() {
        int CASE;scanf("%d",&CASE);
        for(int _=1;_<=CASE;_++){
            sam::init();
            int n;scanf("%d",&n);
            cin>>sam::s;
            for(int i=1;i<=n-1;++i){
                string t;   cin>>t;
                if(i-1) sam::insert('a'+26);
                for(auto j:t) sam::insert(j);
            }
            sam::solve();
            printf("Case #%d: ",_);
            if(sam::ans=="") printf("Impossible
    ");
            else cout<<sam::ans<<"
    ";
        }
        return 0;
    }
    
  • 相关阅读:
    学习Java书籍推荐和面试网站推荐
    Java 多线程学习扩展
    Java Excel 导入导出(二)
    Java Excel 导入导出(一)
    Matplotlib库(二)
    Matplotlib库(一)
    【转】MATLAB导出精美的论文插图
    图像的手绘效果
    Numpy库的使用(二)
    Numpy库的使用(一)
  • 原文地址:https://www.cnblogs.com/CADCADCAD/p/13773478.html
Copyright © 2011-2022 走看看