【Trie图】BZOJ3940-[Usaco2015 Feb]Censoring

【题目大意】

有一个匹配串和多个模式串,现在不断删去匹配串中的模式串,求出最后匹配串剩下的部分。

【思路】

众所周知,KMP的题往往对应着一道AC自动机quq。本题同BZOJ3942(KMP),这里改成AC自动机即可。

我一开始写了原始的AC自动机,写挂了。后来思考了一下,应当用Trie图,机智地1A。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 using namespace std;
  7 const int MAXN=100000+50;
  8 char str[MAXN];
  9 int n,cnt;
 10 struct ACauto
 11 {
 12     ACauto* next[26];
 13     ACauto* fail;
 14     int id;
 15     int sign;
 16     ACauto()
 17     {
 18         for (int i=0;i<26;i++) next[i]=NULL;
 19         fail=NULL;
 20         id=++cnt;
 21         sign=0;
 22     }
 23 };
 24 
 25 ACauto* rt=new ACauto();
 26 
 27 void insert(char* s,ACauto* rt)
 28 {
 29     ACauto* tmp=rt;
 30     for (int i=0;s[i];i++)
 31     {
 32         int index=s[i]-'a';
 33         if (tmp->next[index]==NULL)
 34             tmp->next[index]=new ACauto();
 35         tmp=tmp->next[index];
 36     }
 37     tmp->sign=strlen(s);
 38 }
 39 
 40 void buildfail(ACauto* rt)//这里我们建立Trie图而不是Trie树的AC自动机 
 41 {
 42     queue<ACauto*> que;
 43     que.push(rt);
 44     while (!que.empty())
 45     {
 46         ACauto* head=que.front();que.pop();
 47         for (int i=0;i<26;i++)
 48         {
 49             if (head->next[i]==NULL)
 50             {
 51                 if (head==rt) head->next[i]=rt;
 52                     else head->next[i]=head->fail->next[i];
 53             }
 54             else
 55             {
 56                 if (head==rt) head->next[i]->fail=rt;
 57                     else
 58                     {
 59                         head->next[i]->fail=head->fail->next[i];
 60                         //if (head->next[i]->fail->sign) head->next[i]->sign=head->next[i]->fail->sign;/*注意!*/
 61                     }
 62                 que.push(head->next[i]);
 63             }
 64         }
 65     }
 66 } 
 67 
 68 void init()
 69 {
 70     cnt=0;
 71     scanf("%s",str);
 72     scanf("%d",&n);
 73     for (int i=0;i<n;i++)
 74     {
 75         char s[MAXN];
 76         scanf("%s",s);
 77         insert(s,rt);
 78     }
 79     buildfail(rt);
 80 }
 81 
 82 void solve()
 83 {
 84     ACauto* a[MAXN];
 85     char stack[MAXN];
 86     int top=0;
 87     a[top]=rt;
 88     for (int i=0;str[i];i++)
 89     {
 90         ACauto* j=a[top];
 91         stack[++top]=str[i];
 92         int index=str[i]-'a';
 93         a[top]=j->next[index];
 94         if (a[top]->sign) top-=a[top]->sign;
 95     }
 96     stack[top+1]='\0';
 97     puts(stack+1);
 98 }
 99 
100 int main()
101 {
102     init();
103     solve();
104     return 0;
105 } 

 

posted @ 2016-08-14 17:33  iiyiyi  阅读(204)  评论(0编辑  收藏  举报