• AC自动机笔记


    AC自动机

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<queue>
     6 #define MAX 100001
     7 #define u(n) (n-'a')
     8 using namespace std;
     9 struct ac{
    10     int son[26],fail,sum;
    11     void init(){
    12         memset(son,0,sizeof(son));
    13         sum=0;
    14     }
    15 }a[500001];
    16 queue<int>q;
    17 int last[500001],ans=0,n,tot=0,len;
    18 char st[1000001],sp[10000][51];
    19 void init(){
    20     for(char i='a';i<='z';i++){
    21         if(a[0].son[u(i)]){
    22             q.push(a[0].son[u(i)]);
    23             a[a[0].son[u(i)]].fail=0;
    24         }
    25     }
    26     while(!q.empty()){
    27         for(char i='a';i<='z';i++){
    28             if(a[q.front()].son[u(i)]){
    29                 q.push(a[q.front()].son[u(i)]);
    30                 int now=a[q.front()].fail;
    31                 while(now&&!a[now].son[u(i)]) now=a[now].fail;
    32                 if(a[now].son[u(i)]) a[q.back()].fail=a[now].son[u(i)];
    33                 else a[q.back()].fail=0;
    34                 if(a[a[q.back()].fail].sum){
    35                     last[q.back()]=a[q.back()].fail;
    36                 }else{
    37                     last[q.back()]=last[a[q.back()].fail];
    38                 }
    39             }
    40         }
    41         q.pop();
    42     }
    43 }
    44 void ins(char st[]){
    45     int s=0;
    46     for(int i=0;i<strlen(st);i++){
    47         if(a[s].son[u(st[i])]==0){
    48             a[s].son[u(st[i])]=++tot;
    49             a[tot].init();
    50             s=tot;
    51         }else{
    52             s=a[s].son[u(st[i])];
    53         }
    54     }
    55     a[s].sum++;
    56 }
    57 void inc(int now){
    58     if(a[now].sum){
    59         ans+=a[now].sum;
    60         a[now].sum=0;
    61     }
    62     while(last[now]){
    63         ans+=a[last[now]].sum;
    64         a[last[now]].sum=0;
    65         now=last[now];
    66     }
    67 }
    68 void solution(int len){
    69     int now=0;
    70     for(int i=0;i<=len;i++){
    71         if(a[now].son[u(st[i])]){
    72             now=a[now].son[u(st[i])];
    73         }else{
    74             while(now&&!a[now].son[u(st[i])]) now=a[now].fail;
    75             if(a[now].son[u(st[i])]) now=a[now].son[u(st[i])];
    76         }
    77         inc(now);
    78     }
    79 }
    80 int main(){
    81     scanf("%d",&n);
    82     a[0].init();
    83     a[0].fail=0;
    84     for(int i=1;i<=n;i++){
    85         scanf("%s",sp[i]);
    86         ins(sp[i]);
    87     }
    88     scanf("%s",st);
    89     len=strlen(st);
    90     init();
    91     solution(len);
    92     printf("%d",ans);
    93     return 0;
    94 }
  • 相关阅读:
    CAN总线布线规范
    使用make_ext4fs时报错,No such file or directory
    安装arm-2009q3交叉编译器后,执行No such file....
    Busybox下make menconfig报错处理!
    解决Markdown转为PDF后,尖括号不能正确显示问题。
    开发板与PC直连 交叉、直连网线做法
    BusyBox tftp使用
    STM32的flash数据页转存过程分析!
    c语言中log函数的使用!
    POJ 3667 Hotel
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/8945112.html
Copyright © 2020-2023  润新知