zoukankan      html  css  js  c++  java
  • bzoj 2946 公共串 —— 后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2946

    建出 n-1 个后缀自动机一起跑呗。

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int const xn=2005;
    int n,lst[10],cnt[10],fa[10][xn<<1],l[10][xn<<1],go[10][xn<<1][30],nw[10];//<<1!!
    char s[10][xn];
    void add(int t,int w)
    {
      int p=lst[t],np=++cnt[t]; lst[t]=np; l[t][np]=l[t][p]+1;
      for(;p&&!go[t][p][w];p=fa[t][p])go[t][p][w]=np;
      if(!p)fa[t][np]=1;
      else
        {
          int q=go[t][p][w];
          if(l[t][q]==l[t][p]+1)fa[t][np]=q;
          else
        {
          int nq=++cnt[t]; l[t][nq]=l[t][p]+1;
          memcpy(go[t][nq],go[t][q],sizeof go[t][q]);
          fa[t][nq]=fa[t][q]; fa[t][q]=fa[t][np]=nq;
          for(;go[t][p][w]==q;p=fa[t][p])go[t][p][w]=nq;
        }
        }
    }
    void build(int t)
    {
      lst[t]=1; cnt[t]=1;
      int len=strlen(s[t]+1);
      for(int i=1;i<=len;i++)add(t,s[t][i]-'a');
    }
    bool trans(int j)
    {
      int w=s[n][j]-'a';
      for(int i=1;i<n;i++)
        {
          if(!go[i][nw[i]][w])return 0;
          nw[i]=go[i][nw[i]][w];
        }
      return 1;
    }
    int main()
    {
      scanf("%d",&n);
      for(int i=1;i<=n;i++)
        {
          scanf("%s",s[i]+1);
          if(i<n)build(i);
        }
      int ans=0,len=strlen(s[n]+1);
      for(int i=1,j;i<=len;i++)
        {
          for(j=1;j<n;j++)nw[j]=1;
          for(j=i;j<=len;j++)if(!trans(j))break;
          ans=max(ans,j-i);
        }
      printf("%d
    ",ans);
      return 0;
    }
  • 相关阅读:
    视频解析小技巧
    linux系统路由设置
    tracert路由跟踪命令
    php+nginx
    docker快速拉取镜像
    linux命令
    添加docker命令
    linux模糊查询文件名
    查看日志
    模板函数与模板类
  • 原文地址:https://www.cnblogs.com/Zinn/p/10108336.html
Copyright © 2011-2022 走看看