zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Selenium系列教程(2)
    如何清除浏览器缓存?
    菜鸟学自动化测试(一)----selenium IDE
    Python风格规范
    NSURLSession使用说明及后台工作流程分析
    iOS如何生成.a文件
    Apple移动设备处理器指令集 armv6、armv7、armv7s及arm64
    使用Xcode和Instruments调试解决iOS内存泄露
    Instruments使用实战
    正则表达式在iOS中的运用
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/5927539.html
Copyright © 2011-2022 走看看