• 【hdu3065-病毒侵袭持续中】AC自动机


    http://acm.hust.edu.cn/vjudge/problem/16405

    题意:给定一些只含大写字母的病毒串,再给一个文本串,问文本串中每个病毒串各出现了多少次

    题解:

    就是用AC自动机,在每个节点末尾有个id记录是哪个单词的末尾,然后如果同时是多个单词的末尾就用一个next数组链状记录当前id的下一个值。
    多组数据坑死人。坑死人。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<queue>
      6 using namespace std;
      7 
      8 const int N=50010,S=2000010,A=26;
      9 int n,num,cnt[N],nt[N],fir[N],sum[N];
     10 char ss[N][65],s[S];
     11 queue<int> q;
     12 struct node{
     13     int id,fail,son[30];
     14 }a[N];
     15 
     16 void clear(int x)
     17 {
     18     a[x].id=a[x].fail=0;
     19     memset(a[x].son,0,sizeof(a[x].son));
     20 }
     21 
     22 void trie(char *c,int id)
     23 {
     24     int x=0,l=strlen(c);
     25     for(int i=0;i<l;i++)
     26     {
     27         int ind=c[i]-'A'+1;
     28         if(!a[x].son[ind])
     29         {
     30             num++;
     31             clear(num);
     32             a[x].son[ind]=num;
     33         }
     34         x=a[x].son[ind];
     35     }
     36     if(!a[x].id) a[x].id=id,fir[x]=id;
     37     else nt[id]=a[x].id,a[x].id=id;
     38 }
     39 
     40 void buildAC()
     41 {
     42     while(!q.empty()) q.pop();
     43     for(int i=1;i<=A;i++)
     44         if(a[0].son[i]) q.push(a[0].son[i]);
     45     while(!q.empty())
     46     {
     47         int x=q.front();q.pop();
     48         int fail=a[x].fail;
     49         for(int i=1;i<=A;i++)
     50         {
     51             if(a[x].son[i])
     52             {
     53                 int y=a[x].son[i],z=a[fail].son[i];
     54                 a[y].fail=z;                
     55                 if(fir[y]) nt[fir[y]]=a[z].id;
     56                 else a[y].id=a[z].id;
     57                 q.push(y);
     58             }
     59             else a[x].son[i]=a[fail].son[i];
     60         }
     61     }
     62 }
     63 
     64 void find(char *c)
     65 {
     66     int x=0,l=strlen(c);
     67     for(int i=0;i<l;i++)
     68     {
     69         if(!(c[i]>='A' && c[i]<='Z')) {x=0;continue;}
     70         int ind=c[i]-'A'+1;
     71         x=a[x].son[ind];
     72         int p=a[x].id;
     73         while(p)
     74         {
     75             sum[p]++;
     76             p=nt[p];
     77         }
     78     }
     79 }
     80 
     81 int main()
     82 {
     83     freopen("a.in","r",stdin);
     84     freopen("a.out","w",stdout);
     85     while(scanf("%d",&n)!=EOF)
     86     {
     87         num=0;
     88         clear(0);
     89         memset(nt,0,sizeof(nt));
     90         memset(fir,0,sizeof(fir));
     91         memset(sum,0,sizeof(sum));
     92         scanf("%d",&n);
     93         for(int i=1;i<=n;i++)
     94         {
     95             scanf("%s",ss[i]);
     96             trie(ss[i],i);
     97         }
     98         buildAC();
     99         scanf("%s",s);
    100         find(s);
    101         for(int i=1;i<=n;i++) 
    102             if(sum[i]) printf("%s: %d
    ",ss[i],sum[i]);    
    103     }
    104 
    105     return 0;
    106 }
  • 相关阅读:
    Codeforces467C George and Job
    Codeforces205E Little Elephant and Furik and RubikLittle Elephant and Furik and Rubik
    Codeforce205C Little Elephant and Interval
    51nod1829 函数
    51nod1574 排列转换
    nowcoder35B 小AA的数列
    Codeforce893E Counting Arrays
    gym101612 Consonant Fencity
    CodeForces559C Gerald and Giant Chess
    CodeForces456D A Lot of Games
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/5686451.html
Copyright © 2020-2023  润新知