HDU 6138 Fleet of the Eternal Throne(AC自动机)

Posted forever97‘s blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 6138 Fleet of the Eternal Throne(AC自动机)相关的知识,希望对你有一定的参考价值。

 

【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=6138

 

【题目大意】

  给出一些串,询问第x个串和第y个串的公共子串,
  同时要求该公共子串为某个串的前缀。求最长符合要求的答案

 

【题解】

  我们对所有串构建AC自动机,将两个询问串之一在AC自动机上mark所有的匹配位置
  另一个串在mark的地方寻找最长匹配即可

 

【代码】

#include <cstdio>
#include <algorithm>
#include <cstring> 
using namespace std;
const int N=100010;
int ans;
namespace AC_DFA{
    const int Csize=27; 
    int tot,son[N][Csize],sum[N],fail[N],q[N],dph[N],vis[N];
    void Initialize(){
        memset(dph,0,sizeof(int)*(tot+1)); 
        memset(fail,0,sizeof(int)*(tot+1));
        memset(sum,0,sizeof(int)*(tot+1));
        for(int i=0;i<=tot;i++)for(int j=0;j<Csize;j++)son[i][j]=0;
        tot=0; fail[0]=-1;
    }
    inline int Tr(char ch){return ch-‘a‘;}
    int Insert(char *s){
        int x=0;
        for(int l=strlen(s),i=0,w;i<l;i++){
            if(!son[x][w=Tr(s[i])]){
                son[x][w]=++tot;
                dph[tot]=i+1;
            }x=son[x][w]; 
        }sum[x]++;
        return x;
    }
    void MakeFail(){
        int h=1,t=0,i,j,x;
        for(i=0;i<Csize;i++)if(son[0][i])q[++t]=son[0][i];
        while(h<=t)for(x=q[h++],i=0;i<Csize;i++)
        if(son[x][i]){
            fail[son[x][i]]=son[fail[x]][i],q[++t]=son[x][i];
        }else son[x][i]=son[fail[x]][i];
    }
    void Cal(char *s){
        memset(vis,0,sizeof(vis));
        for(int l=strlen(s),i=0,x=0,w;i<l;i++){
            while(!son[x][Tr(s[i])])x=fail[x];
            x=son[x][Tr(s[i])];
            for(int j=x;j;j=fail[j])vis[j]=1;
        }
    }
    void Find(char *s){
        for(int l=strlen(s),i=0,x=0,w;i<l;i++){
            while(!son[x][Tr(s[i])])x=fail[x];
            x=son[x][Tr(s[i])];
            for(int j=x;j;j=fail[j])if(vis[j])ans=max(ans,dph[j]);
        }
    }
}
char s[110][N];
int T,n;
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        using namespace AC_DFA;
        Initialize();
        for(int i=1;i<=n;i++){
            scanf("%s",s[i]);
            Insert(s[i]);
        }int q;
        MakeFail();
        scanf("%d",&q);
        while(q--){
            int x,y; ans=0;
            scanf("%d%d",&x,&y);
            Cal(s[x]); Find(s[y]);
            printf("%d\n",ans);
        }
    }return 0;
}

 

以上是关于HDU 6138 Fleet of the Eternal Throne(AC自动机)的主要内容,如果未能解决你的问题,请参考以下文章

Fleet of the Eternal Throne HDU6138

2017多校第8场 HDU 6138 Fleet of the Eternal Throne AC自动机或者KMP

hdu 5318 The Goddess Of The Moon

HDU 1010 Tempter of the Bone

hdu 5318 The Goddess Of The Moon 矩阵高速幂

hdu 1010 Tempter of the Bone