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\n", 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;

 

posted on 2015-08-27 15:22  一个西瓜  阅读(189)  评论(0编辑  收藏  举报

导航