zoukankan      html  css  js  c++  java
  • 【bzoj3940】[Usaco2015 Feb]Censoring

    【题目描述】

    FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过10^5的字符串S。他有一个包含n个单词的列表,列表里的n个单词
    记为t_1...t_N。他希望从S中删除这些单词。 
    FJ每次在S中找到最早出现的列表中的单词(最早出现指该单词的开始位置最小),然后从S中删除这个单词。他重复这个操作直到S中
    没有列表里的单词为止。注意删除一个单词后可能会导致S中出现另一个列表中的单词 
    FJ注意到列表中的单词不会出现一个单词是另一个单词子串的情况,这意味着每个列表中的单词在S中出现的开始位置是互不相同的 
    请帮助FJ完成这些操作并输出最后的S
    【样例输入】
    begintheescapexecutionatthebreakofdawn
    2
    escape
    execution
    【样例输出】
    beginthatthebreakofdawn
     
    【题解】
    和p3942一样的思路(连题目名字都一样),建议先写p3942,我可以说这个东西叫可持久化AC自动机吗?(并没有这个东西)
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<ctime>
     6 #include<cmath>
     7 #include<algorithm>
     8 using namespace std;
     9 #define MAXN 100010
    10 int n,cnt,top,end[MAXN],fail[MAXN],deep[MAXN],f[MAXN],q[MAXN],stack[MAXN],tr[MAXN][27];
    11 char b[MAXN],ch[MAXN];
    12 void insert()
    13 {
    14     int now=0,len=strlen(ch+1);
    15     for(int i=1;i<=len;i++)
    16     {
    17         if(!tr[now][ch[i]-'a']) tr[now][ch[i]-'a']=++cnt;
    18         now=tr[now][ch[i]-'a'];
    19     }
    20     end[now]=max(end[now],len);
    21 }
    22 void build()
    23 {
    24     int head=0,tail=0;
    25     for(int i=0;i<26;i++)  if(tr[0][i])  q[++tail]=tr[0][i];
    26     while(++head<=tail)
    27     {
    28         int x=q[head];
    29         for(int i=0;i<26;i++)
    30         {
    31             if(!tr[x][i])  tr[x][i]=tr[fail[x]][i];
    32             else {fail[tr[x][i]]=tr[fail[x]][i]; q[++tail]=tr[x][i];}
    33         }
    34     }
    35 }
    36 void find()
    37 {
    38     int len=strlen(b+1);
    39     for(int i=1,x=0;i<=len;i++)
    40     {
    41         f[i]=tr[f[stack[top]]][b[i]-'a'];
    42         stack[++top]=i;
    43         top-=end[f[i]];
    44     }
    45 }
    46 int main()
    47 {
    48     //freopen("cin.in","r",stdin);
    49     //freopen("cout.out","w",stdout);
    50     scanf("%s%d",b+1,&n);
    51     for(int i=1;i<=n;i++)  {scanf("%s",ch+1);  insert();}
    52     build();
    53     find();
    54     for(int i=1;i<=top;i++)  printf("%c",b[stack[i]]);
    55     return 0;
    56 }
  • 相关阅读:
    从联想昭阳到MacBook Pro,致我的那些败家玩意——电脑
    讲真,这两款idea插件,能治愈你英语不好的病
    大专学历以后就职会不会有瓶颈
    恕我直言,我怀疑你并不会生成随机数
    一文教会你如何在 Spring 中进行集成测试,太赞了
    30岁开始学编程晚吗?
    delphi下TList的用法
    在Delphi下基于MapWinGIS添加和删除图层标注的方法
    SMS模型格网转换为MIKE21的格网源代码
    样条曲线的Fortran程序
  • 原文地址:https://www.cnblogs.com/chty/p/6006415.html
Copyright © 2011-2022 走看看