zoukankan      html  css  js  c++  java
  • AC自动机模板,可重新build

    struct AC_automation {
        int L;
        int next[maxnode][sigma_size];
        int val[maxnode];
        int fail[maxnode], last[maxnode];
        int newnode()
        {
            memset(next[L],0,sizeof(next[L]));
            fail[L] = last[L]  = val[L]  = 0;
            return L++;
        } //新建结点
        void init() {
            memset(next[0], 0, sizeof(next[0]));
            fail[0] = last[0] = val[0] = 0;
            L = 1;
        }// 初始化
    
        inline int idx(char c) {
            return c - '0';
        }
    
        int insert(const char *str) {
            int len = strlen(str), u = 0;
            for(int i = 0; i < len; i++) {
                int c = idx(str[i]);
                if(next[u][c] == 0) {
                    memset(next[L], 0, sizeof(next[L]));
                    fail[L] = last[L] = val[L] = 0;
                    next[u][c] = L++;
                }
                u = next[u][c];
            }
            int ret = val[u];
            val[u] = 1;
            return !ret;
        }// 插入字典树
    
        bool ask(const char *str) {
            int len = strlen(str), u = 0;
            for(int i = 0; i < len; i++) {
                int c = idx(str[i]);
                if(next[u][c] == 0) return false;
                u = next[u][c];
            }
            return val[u];
        } // 存不存在
    
        void build() {
            std::queue<int> q;
            int u = 0;
            fail[0] = 0; 
            for(int c = 0; c < sigma_size; c++) {
                int u = next[0][c];
                if(u) { fail[u] = last[u] = 0; q.push(u); }
            }
            while(!q.empty()) {
                int r = q.front(); q.pop();
                for(int c = 0; c < sigma_size; c++) {
                    int u = next[r][c];
                    if(!u) continue;
                    q.push(u);
                    int v = fail[r];
                    while(v && !next[v][c]) v = fail[v];
                    fail[u] = next[v][c];
                    last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
                }
            }
        }//get-fail
    
        void calc(int now, int &ans) {
            if(now) {
                ans += val[now];
                calc(last[now], ans);
            }
        }
    
        int query(char *str) {
            //printf("query %s
    ", str);
            int len = strlen(str), u = 0;
            int ans = 0;
            for(int i = 0; i < len; i++) {
                int c = idx(str[i]);
                while(u && !next[u][c]) u = fail[u];
                u = next[u][c];
                if(val[u]) calc(u, ans);
                else if(last[u]) calc(last[u], ans);
            }
            return ans;
        }// 查询出现次数
    }ac1,ac2;
  • 相关阅读:
    MySQL数据库之索引
    python面向对象编程
    linux端口占用
    lintcode
    java基础
    lintcode
    linux 常用命令
    Docker & Kubernates
    angular preparation
    java 命令行
  • 原文地址:https://www.cnblogs.com/yigexigua/p/4763425.html
Copyright © 2011-2022 走看看