zoukankan      html  css  js  c++  java
  • 模板—AC自动机

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 using namespace std;
      5 struct trie
      6 {
      7     int count;
      8     trie *next[26],*fail;
      9 }*q[5000000];
     10 int head,tail;
     11 char keyword[55];
     12 char str[1000010];
     13 
     14 trie *Newtrie()
     15 {
     16     int i;
     17     trie *temp=new trie;
     18     temp->count=0;
     19     for(int i=0;i<26;i++)temp->next[i]=NULL;
     20     temp->fail=NULL;
     21     return temp;
     22 }
     23 void insert(trie *p,char s[])
     24 {
     25     int i=0,index;
     26     trie *temp=p;
     27     while(s[i])
     28     {
     29         index=s[i]-'a';
     30         if(temp->next[index]==NULL)temp->next[index]=Newtrie();
     31         temp=temp->next[index];
     32         i++;
     33     }
     34     temp->count++;
     35 }
     36 void build_ac(trie *root)
     37 {
     38     int i=0,index;
     39     q[++tail]=root;
     40     root->fail=NULL;
     41     while(head!=tail)
     42     {
     43         trie *temp=q[++head];
     44         trie *p=NULL;
     45         for(int i=0;i<26;i++)
     46         {
     47             if(temp->next[i]!=NULL)
     48             {
     49                 if(temp==root) temp->next[i]->fail=root;
     50                 else
     51                 {
     52                     p=temp->fail;
     53                     while(p!=NULL)
     54                     {
     55                         if(p->next[i]!=NULL)
     56                         {
     57                             temp->next[i]->fail=p->next[i];
     58                             break;
     59                         }
     60                         p=p->fail;
     61                     }
     62                     if(p==NULL) temp->next[i]->fail=root;
     63                 }
     64                 q[++tail]=temp->next[i];
     65             }
     66         }
     67     }
     68 }
     69 int ask(trie *root)
     70 {
     71     int i=0,cnt=0,index,len;
     72     len=strlen(str);
     73     trie *p=root;
     74     while(str[i])
     75     {
     76         index=str[i]-'a';
     77         while(p->next[index]==NULL && p!=root)p=p->fail;
     78         p=p->next[index];
     79         if(p==NULL)p=root;
     80         trie *temp=p;
     81         while(temp!=root && temp->count!=-1)
     82         {
     83             cnt+=temp->count;
     84             temp->count=-1;
     85             temp=temp->fail;
     86         }
     87         i++;
     88     }
     89     return cnt;
     90 }
     91 signed main()
     92 {
     93     int n,T;
     94     trie *p;
     95     cin>>T;
     96     while(T--)
     97     {
     98         p=Newtrie();
     99         cin>>n;
    100         for(int i=1;i<=n;i++)
    101         {
    102             cin>>keyword;
    103             insert(p,keyword);
    104         }
    105         cin>>str;
    106         build_ac(p);
    107         cout<<ask(p)<<endl;
    108     }
    109 }
    波澜前,面不惊。
  • 相关阅读:
    LeetCode20 有效的括号
    函数的多个参数
    定义一个函数的基本语法 函数的参数
    函数
    金字塔
    水仙花数
    百鸡百钱
    循环demo
    while适用于不确定循环次数
    浏览器打断点
  • 原文地址:https://www.cnblogs.com/Al-Ca/p/11019227.html
Copyright © 2011-2022 走看看