• AC自动机(BZOJ1030)


    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    
      const int mo=10007;
      
      int cnt;
      
      int trie[6101][31];
      int val[6101];
      int f[6101],last[6101];
      int n,m;
      char st[61][101];
      int tmp[101];
      int dp[101][6101][2];
    
      int newnode(){
          return(++cnt);
      }
    
      void ins(int a[],int len){
          int t=0;
          for (int i=1;i<=len;i++){
            if (trie[t][a[i]]==0) t=trie[t][a[i]]=newnode();else 
                                t=trie[t][a[i]];    
        }
        val[t]=1;
      }
      
      queue <int> q;
      void getfail(){
          for (int i=1;i<=26;i++) 
            if (trie[0][i]){
              q.push(trie[0][i]);
            f[trie[0][i]]=last[trie[0][i]]=0;    
          }
          
        while (!q.empty()){
          int t=q.front();q.pop();
          for (int i=1;i<=26;i++){
              int u=trie[t][i];
              if (u==0) {trie[t][i]=trie[f[t]][i];continue;}
              q.push(u);
              f[u]=trie[f[t]][i];
              if (val[f[u]]) last[u]=f[u]/*,val[u]=1*/;else last[u]=last[f[u]];
          }    
        }  
      }
    
      int main(){
          scanf("%d%d",&n,&m);
          for (int i=1;i<=n;i++){
            scanf("%s",&st[i]);
          int le=strlen(st[i]);
          for (int j=1;j<=le;j++) tmp[j]=st[i][j-1]-'A'+1;
          ins(tmp,le);    
        }
        
        getfail();
        
        dp[0][0][0]=1;
        for (int i=0;i<m;i++)
          for (int j=0;j<=cnt;j++){
            if (dp[i][j][0]){
              for (int k=1;k<=26;k++)
               if (val[trie[j][k]])
                dp[i+1][trie[j][k]][1]+=dp[i][j][0],dp[i+1][trie[j][k]][1]%=mo;else
                dp[i+1][trie[j][k]][0]+=dp[i][j][0],dp[i+1][trie[j][k]][0]%=mo;
            }
            if (dp[i][j][1]){
              for (int k=1;k<=26;k++)
                dp[i+1][trie[j][k]][1]+=dp[i][j][1],dp[i+1][trie[j][k]][1]%=mo;    
            }
        }
            
        int ans=0;
        for (int i=0;i<=cnt;i++)
          ans+=dp[m][i][1],ans%=mo;
        
        printf("%d
    ",ans);  
      }

    自动机中一个节点对应了多个串,如此题中虽在字典树中非叶子节点,但可能对应了一个串

    例:abab,ba,在到达找寻aba时实际已找到ba

  • 相关阅读:
    每周进度条(第九周)
    团队项目最后更改版
    项目需求分析与建议 NABCD模型
    课堂练习找水王
    问题账户需求分析
    2016年秋季个人阅读计划
    学习进度条
    用户体验
    程序员修炼之道——从小工到专家阅读笔记03
    程序员修炼之道——从小工到专家阅读笔记02
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/5927539.html
Copyright © 2020-2023  润新知