zoukankan      html  css  js  c++  java
  • P3121 [USACO15FEB]审查(黄金)Censoring (Gold)

    P3121 [USACO15FEB]审查(黄金)Censoring (Gold)

    思路:

    首先构造AC自动机,然后那串去匹配,并且记录一下每一个字符匹配时在AC自动机上的位置。
    如果成功匹配一个单词,那么就需要从串中删除这个单词,并且从之前标记的位置开始匹配。
    因为单词的长度我们知道,所以直接利用一个数组模拟的栈来搞就行。

    代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 2e5+5;
    int n,top;
    char s[N],t[N];
    int sta[N];
    int Skip[N];
    queue <int> q;
    struct Aho_Corasick{
        int Size;
        int ch[N][30];
        int val[N];
        int fail[N];
        void init(){
            Size=-1;
            newnode();
        }
        int newnode(){
            memset(ch[++Size],0,sizeof(ch[0]));
            val[Size]=fail[Size]=0;
            return Size;
        }
        void insert(char *s){
            int l=strlen(s);
            int u=0;
            for(int i=0;i<l;i++){
                int idx=s[i]-'a';
                if(!ch[u][idx]) ch[u][idx]=newnode();
                u=ch[u][idx];
            }
            val[u]=l;
        }
        void Getfail(){
            while(!q.empty()) q.pop();
            for(int i=0;i<26;i++){
                if(ch[0][i]) q.push(ch[0][i]);
            }
            while(!q.empty()){
                int cur=q.front();q.pop();
                for(int i=0;i<26;i++){
                    if(ch[cur][i]){
                        fail[ch[cur][i]]=ch[fail[cur]][i];
                        q.push(ch[cur][i]);
                    }else{
                        ch[cur][i]=ch[fail[cur]][i];
                    }
                }
            }
        }
        void query(char *s){
            int l=strlen(s);
            int u=0;
            for(int i=0;i<l;i++){
                int idx = s[i]-'a';
                sta[++top]=i;
                int cur = ch[u][idx];
                Skip[top]=cur;
                if(val[cur]){
                    //cout<<top<<" "<<val[cur]<<endl;
                    top-=val[cur];
                    u=Skip[top];
                    continue ;
                }
                u=cur;
            }
        }
    }ac;
    int main(){
        //freopen("testdata.in","r",stdin);
        //freopen("testdate",)
        scanf("%s",s);
        scanf("%d",&n);
        ac.init();
        for(int i=1;i<=n;i++){
            scanf("%s",t);
            ac.insert(t);
        }
        ac.Getfail();
        ac.query(s);
        for(int i=1;i<=top;i++) printf("%c",s[sta[i]]);
        printf("
    ");
        return 0;
    }
    /*
    abbababaab
    3
    baa
    bab
    aab
    */
    
    
    
  • 相关阅读:
    2、react-生命周期1※※※
    4.vue class 绑定- model基础应用
    1.react的基础
    Leetcode 5429 数组中的 k 个最强值
    leetcode 21.合并两个有序链表(迭代)
    【Postman请求无响应】Can not get any response
    【PageHelper】插件不生效的原因及解决办法
    【fasterxml.jackson】字段(反)序列号问题Access.WRITE_ONLY
    【SpringCloud-Maven】依赖版本比对
    【Charles】抓包工具使用
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10877743.html
Copyright © 2011-2022 走看看