ac自动机模版

struct AC {
    int ans, total, val[MAXN], fail[MAXN];//ans保存题目解,total分配新节点,val存节点值,fail是失配指针
    int child[MAXN][SIZE];

    void init() {//使用ac自动机前务必初始化
        ans = 0; total = 1;
        memset(val, 0, sizeof(val));
        memset(fail, 0, sizeof(fail));
        memset(child[0], 0, sizeof(child[0]));
    }
    void Insert(const char *P) {//构造字典树
        int root = 0;
        for (int i = 0; P[i]; i++) {
            if (!child[root][P[i] - 'a']) {
                memset(child[total], 0, sizeof(child[total]));
                child[root][P[i] - 'a'] = total++;
            }
            root = child[root][P[i] - 'a'];
        }
        val[root]++;
    }
    void Getfail() {//bfs构造fail指针
        queue<int> q;
        for (int i = 0; i < SIZE; i++) {//首先把root的所有儿子的fail指针都指向root
            if (child[0][i]) q.push(child[0][i]);//因为节点的fail指针默认为root所以就简写了
        }
        while (!q.empty()) {
            int root = q.front(); q.pop();
            for (int i = 0; i < SIZE; i++) {
                int u = child[root][i];
                if (!u) { child[root][i] = child[fail[root]][i]; continue; }//Trie图优化,建立失配边
                q.push(u);
                int v = fail[root];
                while (v && !child[v][i]) v = fail[v];//构造fail指针的关键,推荐画图辅助理解
                fail[u] = child[v][i];
            }
        }
    }
    void Search(const char *T) {
        Getfail();
        int root = 0, temp;
        for (int i = 0; T[i]; i++) {
            temp = root = child[root][T[i] - 'a'];//因为经过了Trie图优化,所以这里只要沿着root走就可以
            while (temp && val[temp]) {//遍历fail路径,防止遗漏
                ans += val[temp];
                val[temp] = 0;//防止重复统计,根据题目而定
                temp = fail[temp];
            }
        }
    }
}ac;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值