zoukankan      html  css  js  c++  java
  • USACO 2015 Feb Censoring

    题目描述

    原题来自:USACO 2015 Feb. Gold

    有一个长度不超过 10510^5105 的字符串 SSS。Farmer John 希望在 SSS 中删掉 nnn 个屏蔽词(一个屏蔽词可能出现多次),这些词记为 t1∼tnt_1sim t_nt1tn

    FJ 在 SSS 中从头开始寻找屏蔽词,一旦找到一个屏蔽词,FJ 就删除它,然后又从头开始寻找(而不是接着往下找)。FJ 会重复这一过程,直到 SSS 中没有屏蔽词为止。注意删除一个单词后可能会导致 SSS 中出现另一个屏蔽词。这 nnn 个屏蔽词不会出现一个单词是另一个单词子串的情况,这意味着每个屏蔽词在 SSS 中出现的开始位置是互不相同的,请帮助 FJ 完成这些操作并输出最后的 SSS。

    输入格式

    第一行包含一个字符串 SSS;
    第二行包含一个整数 nnn;
    接下来的 nnn 行,每行包含一个字符串,第 iii 行的字符串是 tit_iti

    输出格式

    一行,输出操作后的 SSS。保证 SSS 不会变成空串。

    样例

    样例输入

    begintheescapexecutionatthebreakofdawn
    2
    escape
    execution

    样例输出

    beginthatthebreakofdawn

    第一眼看到,以为是bzoj3942,然后就被dalao鄙视了
    但是这道题的思想和那道题很像,只不过是把操作过程中的KMP换成了AC自动机
    只需要在匹配成功后出栈,中级记录一个可持久化的数组,用来存出栈后从Trie树的那个节点开始重新匹配
    下面给出代码:
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath>
    using namespace std;
    inline int rd(){
        int x=0,f=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
        return x*f;
    }
    inline void write(int x){
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
        return ;
    }
    char s[1000006];
    char a[1000006];
    int n,len=0;
    int trie[1000006][30];
    int tot=1;
    int vis[1000006];
    void pre(){
        int c=1;
        for(int i=1;i<=len;i++){
            int h=a[i]-'a';
            if(!trie[c][h]) trie[c][h]=++tot;
            c=trie[c][h];
        }
        vis[c]=len;
        return ;
    }
    int nxt[1000006];
    int q[1000006];
    int l=0,r=0;
    void get_next(){
        q[++r]=1;
        for(int i=0;i<=25;i++) trie[0][i]=1;
        nxt[1]=0;
        while(l<r){
            int h=q[++l];
            for(int i=0;i<=25;i++){
                if(!trie[h][i]) trie[h][i]=trie[nxt[h]][i];
                else{
                    nxt[trie[h][i]]=trie[nxt[h]][i];
                    q[++r]=trie[h][i];
                }
            }
        }
        return ;
    }
    int sk[1000006];
    int cnt=0;
    int loc[1000006];
    void solve(){
        int m=strlen(s+1);
        int c=1;
        for(int i=1;i<=m;i++){
            sk[++cnt]=i;
            int h=s[i]-'a';
            int y=trie[c][h];
            if(trie[c][h]){
                if(vis[trie[c][h]]){
                    cnt-=vis[trie[c][h]];
                    c=loc[sk[cnt]];
                    continue;
                }
            }
            c=y;
            loc[i]=y;
        }
        return ;
    }
    int main(){
        scanf("%s",s+1);
        n=rd();
        for(int i=1;i<=n;i++){
            scanf("%s",a+1);
            len=strlen(a+1);
            pre();
        }
        get_next();
        solve();
        for(int i=1;i<=cnt;i++) printf("%c",s[sk[i]]);
        return 0;
    }
    蒟蒻总是更懂你✿✿ヽ(°▽°)ノ✿
  • 相关阅读:
    IfcFurnishingElementType
    IfcRelAssociatesClassification
    IfcRelAssociatesDocument
    IfcContext
    IfcRelAssociatesMaterial
    我是高敏感的人,你呢?
    介绍一本红色的书
    矫枉必须过正
    大家都在说的民法典,与我有何关系?
    线上Kafka突发rebalance异常,如何快速解决?
  • 原文地址:https://www.cnblogs.com/WWHHTT/p/9750292.html
Copyright © 2011-2022 走看看