zoukankan      html  css  js  c++  java
  • 【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]='';
     97     puts(stack+1);
     98 }
     99 
    100 int main()
    101 {
    102     init();
    103     solve();
    104     return 0;
    105 } 
  • 相关阅读:
    三种renderman规范引擎的dice对比
    球形环境映射之angular与latlong格式互换
    SharePoint中的ASHX
    如何查看SharePoint未知错误的详细信息
    在SQL Server 2008设置发送邮件步骤详解
    项目管理软件对比
    海外云服务器VPS
    国内和国外域名注册商介绍
    快速将一个表的数据生成SQL插入语句
    使用sql server 链接服务器
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5770594.html
Copyright © 2011-2022 走看看