zoukankan      html  css  js  c++  java
  • AC自动机

    前言

    其实AC自动机就是多模式匹配,运用trie和kmp把时间复杂度优化到线性的O(N)。

    一、建trie

    trie就不多说了,相信大家都会

    void put()
    {
        int now=1,len=strlen(s1+1);
        for(int i=1;i<=len;i++)
        {
            if(!trie[now].c[s1[i]-'a']) trie[now].c[s1[i]-'a']=++tot;
            trie[trie[now].c[s1[i]-'a']].deep=trie[now].deep+1;
            now=trie[now].c[s1[i]-'a'];
        }
        trie[now].w=1;
    }
    

    二、构建fail(失败指针)

    fail(失败指针)其实就是类似于kmp的next数组,是AC自动机的核心。
    如果会kmp的话,应该也不能难解。
    可以通过一幅图来理解一下
    这里写图片描述

    void makefail()
    {
        int head=0,tail=1,now=1;
        d[1]=1;
        trie[1].fail=0;
        while(head<tail)
        {
            int k=d[++head],p=0;
            for(int i=0;i<26;i++)
            {
                if(!trie[k].c[i]) continue;
                p=trie[k].c[i];
                int z=trie[k].fail;
                while(z && !trie[z].c[i]) z=trie[z].fail;
                trie[p].fail=trie[z].c[i];
                trie[p].fail=trie[p].fail?trie[p].fail:1;
                d[++tail]=p;
            }
        }
    }
    

    三、查询

    当每次确定了一个节点后顺着fail构成了链向上走,避免漏算以现在搜到的状态为后缀的字符串。

    int find()
    {
    	int j=1;
    	for(int i=1;i<=n;i++)
    	{
    		int index=s[i]-'a';
    		while(j!=1 && !trie[j].c[index]) j=trie[j].fail;
    		j=trie[j].c[index];
    		j=j?j:1;
    		int p=j;
    		while(p!=1)
    		{
    			if(trie[p].w) ans++;
    			p=trie[p].fail;
    			trie[p].w--;
    		}
    	}
    }
    

    当然,不能直接打模板,根据每到题目的不同来分析运用,有时要加点优化。


    模板题【GDOI2013模拟4】贴瓷砖

  • 相关阅读:
    70.BOM
    69.捕获错误try catch
    68.键盘事件
    523. Continuous Subarray Sum
    901. Online Stock Span
    547. Friend Circles
    162. Find Peak Element
    1008. Construct Binary Search Tree from Preorder Traversal
    889. Construct Binary Tree from Preorder and Postorder Traversal
    106. Construct Binary Tree from Inorder and Postorder Traversal
  • 原文地址:https://www.cnblogs.com/chen1352/p/9048120.html
Copyright © 2011-2022 走看看