• 【字符串】AC自动机


    struct ACM {
    
        static const int MAXN = 1e6 + 10;
    
        int ch[MAXN][26], fail[MAXN];
        int cnt;
    
        int R[MAXN];
    
        void Init() {
            ms(ch[0]), fail[0] = 0;
            cnt = 0;
        }
    
        int NewNode() {
            int o = ++cnt;
            ms(ch[o]);
            fail[o] = 0;
            R[o] = 0;
            return o;
        }
    
        void Insert(char *s) {
            int u = 0;
            for (int i = 1; s[i]; ++i) {
                if (!ch[u][s[i] - 'a'])
                    ch[u][s[i] - 'a'] = NewNode();
                u = ch[u][s[i] - 'a'];
            }
            ++R[u];
        }
    
        void Build() {
            static queue<int> Q;
            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 u = Q.front();
                Q.pop();
                for(int i = 0; i < 26; ++i) {
                    if(ch[u][i]) {
                        fail[ch[u][i]] = ch[fail[u]][i];
                        Q.push(ch[u][i]);
                    } else {
                        ch[u][i] = ch[fail[u]][i];
                    }
                }
            }
        }
    
        int Query(char *t) {
            int u = 0, res = 0;
            for (int i = 1; t[i]; ++i) {
                u = ch[u][t[i] - 'a'];
                for (int j = u; j && R[j] != -1; j = fail[j])
                    res += R[j], R[j] = -1;
            }
            return res;
        }
    
    } acm;
    

    AC自动机 二次加强版

    struct ACM {
    
        static const int MAXN = 2e6 + 10;
    
        int ch[MAXN][26], fail[MAXN];
        int cnt;
    
        vector<int> R[MAXN];
        vector<int> G[MAXN];
    
        void Init() {
            ms(ch[0]), fail[0] = 0;
            cnt = 0;
        }
    
        int NewNode() {
            int o = ++cnt;
            ms(ch[o]);
            fail[o] = 0;
            R[o].clear();
            return o;
        }
    
        void Insert(char *s, int id) {
            int u = 0;
            for (int i = 1; s[i]; ++i) {
                if (!ch[u][s[i] - 'a'])
                    ch[u][s[i] - 'a'] = NewNode();
                u = ch[u][s[i] - 'a'];
            }
            R[u].eb(id);
        }
    
        void Build() {
            static queue<int> Q;
            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 u = Q.front();
                Q.pop();
                for(int i = 0; i < 26; ++i) {
                    if(ch[u][i]) {
                        fail[ch[u][i]] = ch[fail[u]][i];
                        Q.push(ch[u][i]);
                    } else {
                        ch[u][i] = ch[fail[u]][i];
                    }
                }
            }
            for(int i = 0; i <= cnt; ++i)
                G[i].clear();
            for(int i = 1; i <= cnt; ++i)
                G[fail[i]].eb(i);
        }
    
        int vis[MAXN], ans[MAXN];
        void dfs(int u) {
            for(int &v : G[u]) {
                dfs(v);
                vis[u] += vis[v];
            }
            for(auto &i : R[u])
                ans[i] = vis[u];
        }
    
        void Query(char *t) {
            for(int i = 0; i <= cnt; ++i)
                vis[i] = 0;
            int u = 0;
            for(int i = 1; t[i]; ++i) {
                u = ch[u][t[i] - 'a'];
                ++vis[u];
            }
            dfs(0);
        }
    
    } acm;
    
  • 相关阅读:
    python的metaclass
    鱼和水的故事
    iOS的QuickTime Plugin
    二进制/十六进制转浮点数的编程(互转类似)
    Android开发常见错误及技巧
    Mac 热键大全
    Java动态程序设计:反射介绍
    注册asp.net 4.0 到iis
    javascript常用判断写法
    将存储过程执行的结果保存到临时表
  • 原文地址:https://www.cnblogs.com/purinliang/p/14076244.html
Copyright © 2020-2023  润新知