zoukankan      html  css  js  c++  java
  • BZOJ 3940 Censoring ( Trie 图 )

    题目链接

    题意 : 中文题、点链接

    分析 :

    直接建 Trie 图、在每一个串的末尾节点记录其整串长度、方便删串操作

    然后对于问询串、由于可能有删串操作

    所以在跑 Trie 图的过程当中需要拿个栈记录一下路径

    跑 Trie 图的意思就是说将问询串字符一个个拿出来

    然后一直找当前节点的下一个对应字母的节点

    由于是 Trie 图、所以在 Fail 的时候也会自动跑到对应的节点

    这和普通的 AC 自动机不一样、在 Fail 的时候要每次暴力跳 Fail 节点

    然后直接模拟即可

    #include<bits/stdc++.h>
    #define LL long long
    #define ULL unsigned long long
    
    #define scl(i) scanf("%lld", &i)
    #define scll(i, j) scanf("%lld %lld", &i, &j)
    #define sclll(i, j, k) scanf("%lld %lld %lld", &i, &j, &k)
    #define scllll(i, j, k, l) scanf("%lld %lld %lld %lld", &i, &j, &k, &l)
    
    #define scs(i) scanf("%s", i)
    #define sci(i) scanf("%d", &i)
    #define scd(i) scanf("%lf", &i)
    #define scIl(i) scanf("%I64d", &i)
    #define scii(i, j) scanf("%d %d", &i, &j)
    #define scdd(i, j) scanf("%lf %lf", &i, &j)
    #define scIll(i, j) scanf("%I64d %I64d", &i, &j)
    #define sciii(i, j, k) scanf("%d %d %d", &i, &j, &k)
    #define scddd(i, j, k) scanf("%lf %lf %lf", &i, &j, &k)
    #define scIlll(i, j, k) scanf("%I64d %I64d %I64d", &i, &j, &k)
    #define sciiii(i, j, k, l) scanf("%d %d %d %d", &i, &j, &k, &l)
    #define scdddd(i, j, k, l) scanf("%lf %lf %lf %lf", &i, &j, &k, &l)
    #define scIllll(i, j, k, l) scanf("%I64d %I64d %I64d %I64d", &i, &j, &k, &l)
    
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    #define lowbit(i) (i & (-i))
    #define mem(i, j) memset(i, j, sizeof(i))
    
    #define fir first
    #define sec second
    #define VI vector<int>
    #define ins(i) insert(i)
    #define pb(i) push_back(i)
    #define pii pair<int, int>
    #define VL vector<long long>
    #define mk(i, j) make_pair(i, j)
    #define all(i) i.begin(), i.end()
    #define pll pair<long long, long long>
    
    #define _TIME 0
    #define _INPUT 0
    #define _OUTPUT 0
    clock_t START, END;
    void __stTIME();
    void __enTIME();
    void __IOPUT();
    using namespace std;
    const int max_node = 2e5 + 10;
    const int max_len = 2e5 + 10;
    const int Letter  = 26;
    
    char ans[max_len];
    int pos[max_len];
    int top = 0;
    
    struct Aho{
        struct StateTable{
            int nxt[Letter];
            int fail, cnt, len;
            bool vis;
            void init(){
                memset(nxt, 0, sizeof(nxt));
                fail = 0;
                cnt = 0;
                len = 0;
                vis = false;
            }
        }Node[max_node];
    
        int sz;
        queue<int> que;
    
        inline void init(){ while(!que.empty())que.pop(); Node[0].init(); sz = 1; }
    
        inline void insert(char *s, int len){
            int now = 0;
            for(int i=0; i<len; i++){
                int idx = s[i] - 'a';
                if(!Node[now].nxt[idx]){
                    Node[sz].init();
                    Node[now].nxt[idx] = sz++;
                }
                now = Node[now].nxt[idx];
            }
            Node[now].len = len;
            Node[now].cnt++;
        }
    
        inline void build(){
            Node[0].fail = -1;
            que.push(0);
            while(!que.empty()){
                int top = que.front();  que.pop();
                for(int i=0; i<Letter; i++){
                    if(Node[top].nxt[i]){
                        if(top == 0) Node[ Node[top].nxt[i] ].fail = 0;
                        else{
                            int v = Node[top].fail;
                            while(v != -1){
                                if(Node[v].nxt[i]){
                                    Node[ Node[top].nxt[i] ].fail = Node[v].nxt[i];
                                    break;
                                }v = Node[v].fail;
                            }if(v == -1) Node[ Node[top].nxt[i] ].fail = 0;
                        }que.push(Node[top].nxt[i]);
                    }else Node[top].nxt[i] = top!=0?Node[ Node[top].fail ].nxt[i]:0;
                }
            }
        }
    
    //    int Match(char *s){
    //        int now = 0, res = 0;
    //        for(int i=0; s[i]!=''; i++){
    //            int idx = s[i] - 'a';
    //            now = Node[now].nxt[idx];
    //            int tmp = now;
    //            while(tmp != 0 && !Node[tmp].vis){
    //                res += Node[tmp].cnt;
    //                Node[tmp].vis = true;
    //                Node[tmp].cnt = 0;
    //                tmp = Node[tmp].fail;
    //            }
    //        }
    //        return res;
    //    }
    
        void query(char * s){
            int len = strlen(s);
            int now = 0;
            pos[now] = now;
            for(int i=0; i<len; i++){
                int idx = s[i] - 'a';
                now = Node[now].nxt[idx];
                pos[++top] = now;
                ans[  top] = s[i];
                if(Node[now].len != 0){
                    top -= Node[now].len;
                    now = pos[top];
                }
            }
            for(int i=1; i<=top; i++) putchar(ans[i]); puts("");
        }
    
    }ac;
    
    char str[max_len];
    char tmp[max_len];
    
    int main(void){__stTIME();__IOPUT();
    
        scs(str);
    
        int len = strlen(str);
    
        int n;
    
        sci(n);
    
        ac.init();
    
        for(int i=0; i<n; i++){
            scs(tmp);
            ac.insert(tmp, strlen(tmp));
        }
    
        ac.build();
    
        ac.query(str);
    
    
    
    __enTIME();return 0;}
    
    
    void __stTIME()
    {
        #if _TIME
            START = clock();
        #endif
    }
    
    void __enTIME()
    {
        #if _TIME
            END = clock();
            cerr<<"execute time = "<<(double)(END-START)/CLOCKS_PER_SEC<<endl;
        #endif
    }
    
    void __IOPUT()
    {
        #if _INPUT
            freopen("in.txt", "r", stdin);
        #endif
        #if _OUTPUT
            freopen("out.txt", "w", stdout);
        #endif
    }
    View Code
  • 相关阅读:
    sql优化
    mysql_存储过程_后一行减去前一行
    python基础笔记
    atom使用markdown
    tensorboard遇到的坑
    WordPaster-Firefox浏览器控件安装方法
    WordPaster.exe安装教程
    Web大文件上传控件-bug修复-Xproer.HttpUploader6
    Web大文件下载控件更新-Xproer.HttpDownloader
    Web大文件上传控件-asp.net-bug修复-Xproer.HttpUploader6.2
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/9508999.html
Copyright © 2011-2022 走看看