• 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;
    }
    
  • 相关阅读:
    Codeforces Round #443 Div. 1
    linux中ps命令
    占cpu 100%的脚本
    检查Linux系统cpu--内存---磁盘的脚本
    jQuery对象的属性操作
    关于js的一些收集
    Linux命令集合
    使用python操作excel表格
    Linux7.3系统 升级python到3.6使用ping主机脚本
    一个别人的线程池的编写
  • 原文地址:https://www.cnblogs.com/CADCADCAD/p/13773478.html
Copyright © 2020-2023  润新知