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

    吐槽

    数据太水了吧,我AC自动机的trie建错了结果只是RE了两个点,还以为数组开小了改了好久

    思路

    看到多模板串,字符串匹配,且模板串总长度不长,就想到AC自动机
    然后用栈维护当前的字符串位置,如果匹配到了,就从栈里逐个弹出对应的字符,并且回溯到匹配这个单词之前的节点
    s每个字符最多会被出栈和入栈各两次,复杂度是(O(n+m))

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <stack>
    using namespace std;
    int trie[410000][26],Nodecnt=0,fail[410000],mark[410000],root,len[410000],n;
    char s[410000],t[410000];
    void insert(char *s,int len,int cnt){
        int o=root;
        for(int i=1;i<=len;i++){
            if(!trie[o][s[i]-'a'])
                trie[o][s[i]-'a']=++Nodecnt;
            o=trie[o][s[i]-'a'];    
        }
        mark[o]=cnt;
    }
    void build_AC(void){
        queue<int> q;
        for(int i=0;i<26;i++){
            if(trie[root][i]){
                fail[trie[root][i]]=root;
                q.push(trie[root][i]);
            }
        } 
        while(!q.empty()){
            int x=q.front();
            q.pop();
            for(int i=0;i<26;i++){
                if(trie[x][i]){
                    fail[trie[x][i]]=trie[fail[x]][i];
                    q.push(trie[x][i]);
                }
                else{
                    trie[x][i]=trie[fail[x]][i];
                }
            }
        }  
    }
    struct SNode{
        int num;
        char c;
    };
    stack<char> S2;
    stack<SNode> S1;
    void query(void){
        int o=root;
        int mid=0;
        while(S2.size()){
            // printf("%d %d
    ",++mid,S1.size());
            char c=S2.top();
            S2.pop();
            o=trie[o][c-'a'];
            if(!mark[o])
                S1.push((SNode){o,c});
            else{
                // printf("begin
    ");
                int p=o;
                for(int i=1;i<=len[mark[p]];i++){
                    if(S1.size())
                        o=S1.top().num;
                    else{
                        o=root;
                        break;
                    }
                    if((!S1.empty())&&i<len[mark[p]])
                        S1.pop();
                    else if(i<len[mark[p]]){
                        o=root;
                        break;
                    }
                }
            }
        }
    }
    void print(void){
        char c=S1.top().c;
        S1.pop();
        if(!S1.empty())
            print();
        putchar(c);
    }
    int main(){
        // freopen("testdata (5).in","r",stdin);
        // freopen("test.out","w",stdout);
        scanf("%s",s+1);
        int lens=strlen(s+1);
        // printf("lens=%d
    ",lens);
        // _sleep(1000);
        for(int i=lens;i>=1;i--)
            S2.push(s[i]);
        // int g=1;
        // for(;g<=lens;g++)
        //     if(s[g]!='a')
        //         break;
        // printf("sa=%d
    ",g-1);
        // _sleep(1000);
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",t+1);
            len[i]=strlen(t+1);
            // printf("len[%d]=%d
    ",i,len[i]);
            // _sleep(1000);
            insert(t,len[i],i);
        }
        build_AC();
        query();
        // printf("ok
    ");
        print();
        printf("
    ");
        return 0;
    }
    
  • 相关阅读:
    js数组删除数组元素!
    ASP.NET安全问题--ASP.NET安全架构
    片滚动插件myScroll
    JS 回车提交,兼容IE、火狐、Opera、Chrome、Safari
    poj_2386_dfs
    poj_1852_Ants(复杂问题简单化)
    File Mapping
    Creating a File View
    next_permutation
    Creating a File Mapping Object
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10454480.html
Copyright © 2011-2022 走看看