• 自动AC机qwq(大雾)以及trie图fail图的一些结论


     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<queue>
     6 #include<algorithm>
     7 #include<cmath>
     8 using namespace std;
     9 const int MAX=1e6,TYPE=26;
    10 struct ac_automation{
    11     int trie[MAX][TYPE],num[MAX],tot,fail[MAX];
    12     void readin(char * a)
    13     {
    14         int k=strlen(a),now=0;
    15         for(int i=0;i<k;i++)
    16         {
    17             if(!trie[now][a[i]-'a'])
    18                 trie[now][a[i]-'a']=++tot;
    19             now=trie[now][a[i]-'a'];
    20         }
    21         num[now]++;
    22     }
    23     void getfail()
    24     {
    25         queue<int> q;
    26         memset(fail,0,sizeof(fail));
    27         for(int i=0;i<TYPE;i++)
    28             if(trie[0][i])
    29                 q.push(trie[0][i]);
    30         while(!q.empty())
    31         {
    32             int k=q.front();
    33             q.pop();
    34             for(int i=0;i<TYPE;i++)
    35                 if(trie[k][i])    
    36                 {
    37                     fail[trie[k][i]]=trie[fail[k]][i];
    38                     q.push(trie[k][i]);
    39                 }
    40                 else
    41                     trie[k][i]=trie[fail[k]][i];
    42         }
    43     }
    44     int find(char *s)
    45     {
    46         int ans=0,p=0;
    47         for(int i=0;s[i];i++)
    48         {
    49             p=trie[p][s[i]-'a'];
    50             for(int j=p;j and ~num[j];j=fail[j])    ans+=num[j],num[j]=-1;
    51         }
    52         return ans;
    53     }
    54 }ac; 
    55 char str[MAX],tem[MAX];
    56 int main()
    57 {
    58     int k;
    59     scanf("%d",&k);
    60     for(int i=1;i<=k;i++)
    61     {
    62         scanf("%s",tem);
    63         ac.readin(tem);
    64     }
    65     scanf("%s",str);
    66     ac.getfail();
    67     printf("%d",ac.find(str));
    68     return 0;
    69 }

     二、一些结论

      1.x的fail指针指向的是x点在这个trie中代表的字符串的在这个trie中的最长后缀

      2.对于一个不在自动机中的字符串s,将其放到自动机中跑,最后停下来时,即到达s的最后一个字符时,假设此时在ac自动机中到了y节点,则y点代表的字符串就是s的最长的,是ac自动机中的字符串的前缀,的后缀。

      3.第一次失配的位置深度(=最长前缀),结束时所在节点深度(=最长后缀);

  • 相关阅读:
    2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 (B,F,L,M)
    Coderfroces 862 C. Mahmoud and Ehab and the xor
    [CQOI 2015] 任务查询系统
    [POI 2014] Couriers
    [POJ 2104] K-th Number
    [模板] 可持久化数组
    [AHOI 2006] 上学路线
    [SCOI2009] 生日礼物
    [BZOJ 3436] 小K的农场
    [USACO2007 Demo] Cow Acrobats
  • 原文地址:https://www.cnblogs.com/member-re/p/10365425.html
Copyright © 2020-2023  润新知