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\n");
        else cout<<sam::ans<<"\n";
    }
    return 0;
}
posted @ 2020-10-06 15:13  caoanda  阅读(163)  评论(0编辑  收藏  举报