• AC自动机


    study from :https://pan.baidu.com/s/1Igr_1EgL5FtB-zpRKosToQ (别人的ppt,如有侵权,请告知我)

    没必要初始化

    如果所有的变量初始值为0/NULL

    如果是多组数据,每次根节点和辅助节点重新创建!

    fail 长度比之间小

    指针 很多个链组成,一个节点,只指向有且只有一个节点;而一个节点,有可能被多个节点指向。同时也是拓扑结构。

    每次bfs搜索:最大代码 点数*26('a'-'z') 链式结构

    可以利用之前的搜索结果

    https://www.luogu.org/problemnew/show/P3808

      1 /*
      2 模式串出现的总次数
      3 */
      4 #include <cstdio>
      5 #include <cstdlib>
      6 #include <cmath>
      7 #include <cstring>
      8 #include <string>
      9 #include <algorithm>
     10 #include <iostream>
     11 using namespace std;
     12 #define ll long long
     13 
     14 const double eps=1e-8;
     15 const ll inf=1e9;
     16 const ll mod=1e9+7;
     17 const int maxn=1e6+10;
     18 
     19 struct node
     20 {
     21     int g,cond;
     22     node *nex[26],*fail,*pre;
     23 }*tr,*be,*p,*pos,*td;
     24 
     25 node *q[maxn];
     26 char str[maxn];
     27 
     28 int main()
     29 {
     30     int n,len,i,head,tail,d,sum=0;
     31     tr=new node();
     32     be=new node();
     33     tr->pre=be;
     34     tr->fail=be;
     35     be->fail=be;
     36     for (i=0;i<26;i++)
     37         be->nex[i]=tr;
     38 
     39     scanf("%d",&n);
     40     while (n--)
     41     {
     42         scanf("%s",str);
     43         pos=tr;
     44         len=strlen(str);
     45         for (i=0;i<len;i++)
     46         {
     47             d=str[i]-97;
     48             if (!pos->nex[d])
     49             {
     50                 p=new node();
     51                 pos->nex[d]=p;
     52                 p->pre=pos;
     53             }
     54             pos=pos->nex[d];
     55         }
     56         pos->g++;
     57     }
     58 
     59     head=0,tail=1;
     60     q[1]=tr;
     61     while (head<tail)
     62     {
     63         head++;
     64         td=q[head];
     65         for (i=0;i<26;i++)
     66             if (td->nex[i])
     67             {
     68                 q[++tail]=td->nex[i];
     69                 pos=td->fail;
     70                 while (!pos->nex[i])
     71                     pos=pos->fail;
     72                 td->nex[i]->fail=pos->nex[i];
     73             }
     74     }
     75 
     76     scanf("%s",str);
     77     len=strlen(str);
     78     pos=tr;
     79     for (i=0;i<len;i++)
     80     {
     81         d=str[i]-97;
     82         while (!pos->nex[d])
     83             pos=pos->fail;
     84         pos=pos->nex[d];
     85 
     86         p=pos;
     87         while (!p->cond)
     88         {
     89             sum+=p->g;
     90             p->cond=1;
     91             p=p->fail;
     92         }
     93     }
     94     printf("%d",sum);
     95     return 0;
     96 }
     97 /*
     98 2
     99 b
    100 a
    101 abcd
    102 
    103 2
    104 ab
    105 ac
    106 abc
    107 
    108 2
    109 ababc
    110 abc
    111 ababc
    112 
    113 3
    114 ab
    115 abc
    116 abca
    117 ababc
    118 
    119 6
    120 ab
    121 abc
    122 abc
    123 abc
    124 abab
    125 ababc
    126 ababc
    127 */

    https://www.luogu.org/problemnew/show/P3796

      1 /*
      2 一个模式串出现的最大次数
      3 */
      4 #include <cstdio>
      5 #include <cstdlib>
      6 #include <cmath>
      7 #include <cstring>
      8 #include <string>
      9 #include <algorithm>
     10 #include <iostream>
     11 using namespace std;
     12 #define ll long long
     13 
     14 const double eps=1e-8;
     15 const ll inf=1e9;
     16 const ll mod=1e9+7;
     17 const int maxn=1e6+10;
     18 
     19 struct node
     20 {
     21 //    char c;
     22     int g,hav;
     23     node *nex[26],*pre,*fail;
     24 }*tr,*be,*p,*pos,*q[maxn],*td;
     25 
     26 int maxg=1,cnt_g,num[150+10];
     27 
     28 char str[maxn],s[150+10][70+10];
     29 
     30 int main()
     31 {
     32     int n,len,i,j,d,head,tail,N;
     33 
     34     while (1)
     35     {
     36         scanf("%d",&n);
     37         if (n==0)
     38             break;
     39 
     40         ///init
     41         tr=new node();
     42         be=new node();
     43         tr->pre=be;
     44         tr->fail=be;
     45         be->fail=be;
     46         for (i=0;i<26;i++)
     47             be->nex[i]=tr;
     48         maxg=1;
     49 
     50         for (N=1;N<=n;N++)
     51         {
     52             scanf("%s",str);
     53             strcpy(s[N],str);
     54 
     55             len=strlen(str);
     56             pos=tr;
     57             for (i=0;i<len;i++)
     58             {
     59                 d=str[i]-97;
     60                 if (!pos->nex[d])
     61                 {
     62                     p=new node();
     63                     pos->nex[d]=p;
     64                     p->pre=pos;
     65 //                    p->c=d;
     66                 }
     67                 pos=pos->nex[d];
     68             }
     69             pos->hav=N;
     70         }
     71 
     72         head=0,tail=1;
     73         q[1]=tr;
     74         while (head<tail)
     75         {
     76             head++;
     77             td=q[head];
     78             for (d=0;d<26;d++)
     79                 if (td->nex[d])
     80                 {
     81                     pos=td->fail;
     82                     while (!pos->nex[d])
     83                         pos=pos->fail;
     84                     td->nex[d]->fail=pos->nex[d];
     85                     q[++tail]=td->nex[d];
     86                 }
     87         }
     88 
     89         scanf("%s",str);
     90         len=strlen(str);
     91         pos=tr;
     92         for (i=0;i<len;i++)
     93         {
     94             d=str[i]-97;
     95             while (!pos->nex[d])
     96                 pos=pos->fail;
     97             pos=pos->nex[d];
     98             pos->g++;
     99         }
    100 
    101         for (i=tail;i>=1;i--)
    102         {
    103             pos=q[i];
    104             if (pos->hav)
    105             {
    106                 if (maxg<=pos->g)
    107                 {
    108                     if (maxg<pos->g)
    109                     {
    110                         maxg=pos->g;
    111                         cnt_g=1;
    112                     }
    113                     else
    114                         cnt_g++;
    115 
    116                     num[cnt_g]=pos->hav;
    117 
    118 //                    j=0;
    119 //                    p=pos;
    120 //                    while (p!=tr)
    121 //                    {
    122 //                        s[cnt_g][j++]=p->c+97;
    123 //                        p=p->pre;
    124 //                    }
    125 //                    s[cnt_g][j]=0;
    126 //                    reverse(s[cnt_g],s[cnt_g]+j);
    127                 }
    128             }
    129             pos->fail->g+=pos->g;
    130         }
    131 
    132         sort(num+1,num+cnt_g+1);
    133         printf("%d
    ",maxg);
    134         for (i=1;i<=cnt_g;i++)
    135             printf("%s
    ",s[num[i]]);
    136 //            printf("%s
    ",s[i]);
    137 
    138         ///free pointer
    139     }
    140     return 0;
    141 }
    142 /*
    143 2
    144 cab
    145 ab
    146 cabcabcab
    147 */
  • 相关阅读:
    C# 日期格式化的中的 正斜杠的问题
    JQuery中如何click中传递参数
    《启示录:打造用户喜爱的产品》—— 读书笔记
    json串的使用
    谷歌浏览器怎么调试js
    web页面布局思想
    js或者cs代码拼接html
    筛选DataTable数据的方法
    Ajax的简单小例子
    简单的javascript例子
  • 原文地址:https://www.cnblogs.com/cmyg/p/9549312.html
Copyright © 2020-2023  润新知