zoukankan      html  css  js  c++  java
  • CENSORING——AC 自动机

    题目

    【题目描述】

    FJ 为它的奶牛订阅了很多杂志,balabala.......,其中有一些奶牛不宜的东西 (比如如何煮牛排)。

    FJ 将杂志中所有的文章提取出来组成一个长度最多为 $ 10^5 $ 的字符串 S。他有一个要从 S 中删除的词语的列表,$ t_1,t_2...t_n $。

    FJ 每次找到最早的出现在列表里的子串,然后将其删去。他重复此过程,直到找不到这样的子串。值得注意的是删除一个单词可能产生一个新的之前并没有出现过的要被删除的单词。

    FJ 保证列表中没有一个字符串是另一个字符串的子串。要就是说每次要删的单词是唯一确定的。

    帮助 FJ 确定最终 S 的删减版。

    【输入格式】

    第一行 S,第二行  $N$,接下来 $n$ 行 $t_1,t_2,...t_n$。所有字符串只包含小写字母,所有字符串的总长不超过 $10^5$。

    【输出格式】

    S 的删减版。保证结果不为空  

    【样例输入】

    begintheescapexecutionatthebreakofdawn
    2
    escape
    execution

    【样例输出】

    beginthatthebreakofdawn

    题解

    对于 T 建 AC 自动机,然后将 $ S $ 逐位压入栈中,跑 AC 自动机,当当前节点为 $ T_i $ 的结尾时,弹出即可

    代码

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 #define _(d) while(d(isdigit(ch=getchar())))
     4 using namespace std;
     5 int R(){
     6     int x;bool f=1;char ch;_(!)if(ch=='-')f=0;x=ch^48;
     7     _()x=(x<<3)+(x<<1)+(ch^48);return f?x:-x;}
     8 const int N=1e5+5;
     9 int n,cnt,fa[N],pre[N],top,num[N],las[N],sta[N],tr[N][28],fail[N];
    10 char str[N],ch[N];
    11 void insert(int k){
    12     int len=strlen(ch+1),x=0;
    13     for(int i=1;i<=len;i++){
    14         if(!tr[x][ch[i]-'a'])tr[x][ch[i]-'a']=++cnt,fa[cnt]=x;
    15         x=tr[x][ch[i]-'a'];
    16     }
    17     num[k]=len,pre[x]=k;
    18 }
    19 void build(){
    20     queue<int>q;
    21     for(int i=0;i<26;i++)
    22         if(tr[0][i])q.push(tr[0][i]);
    23     while(!q.empty()){
    24         int x=q.front();q.pop();
    25         for(int i=0;i<26;i++)
    26             if(tr[x][i])
    27                 fail[tr[x][i]]=tr[fail[x]][i],q.push(tr[x][i]);
    28             else tr[x][i]=tr[fail[x]][i];
    29     }
    30 }
    31 int main(){
    32     scanf("%s",str+1);
    33     int len=strlen(str+1);n=R();
    34     for(int i=1;i<=n;i++)
    35         scanf("%s",ch+1),insert(i);
    36     build();
    37     for(int i=1,x=0;i<=len;i++){
    38         sta[++top]=i;
    39         int p=str[i]-'a',y=tr[x][p];
    40         if(y&&pre[y])
    41             top-=num[pre[y]],x=las[sta[top]];
    42         else las[i]=x=y;
    43     }
    44     for(int i=1;i<=top;i++)
    45         putchar(str[sta[i]]);
    46     return puts(""),0;
    47 }
    View Code
  • 相关阅读:
    快速入门系列--MVC--07与HTML5移动开发的结合
    快速入门系列--WebAPI--01基础
    快速入门系列--CLR--02多线程
    MongoDB快速入门
    ubuntu 12.04 server编译安装nginx
    apache 正反向代理
    c# 继承,多态,new /overrid 区别, 引用父类的方法
    python 异步线程简单实现
    ubuntu上完全卸载package
    apache2:Invalid option to WSGI daemon process definition
  • 原文地址:https://www.cnblogs.com/chmwt/p/10662042.html
Copyright © 2011-2022 走看看