zoukankan      html  css  js  c++  java
  • 洛谷P3808 【模板】AC自动机(简单版)

    模板AC自动机

    #include<bits/stdc++.h>
    #define maxn 5005
    #define ll long long
    const ll mod=1e9+7;
    using namespace std;
    const int N = 1e6+10;
    const double pi = acos(-1.0);
    struct Tree{
        int fail;//失配指针
        int vis[26];//子节点的位置
        int end;//标记有几个单词以这个节点结尾
    }AC[N];//trie树
    int cnt = 0;//Trie的指针
    inline void Build(string s)
    {
        int l = s.length();
        int now = 0;
        for(int i=0;i<l;i++)
        {
            if(AC[now].vis[s[i]-'a'] == 0)//Trie树没有这个子节点
            {
                AC[now].vis[s[i]-'a'] = ++cnt;//构造出来
            }
            now = AC[now].vis[s[i]-'a'];//向下构造
        }
        AC[now].end += 1;//标记单词结尾
    }
    void Get_fail()//构造fail指针
    {
        queue<int>Q;
        for(int i=0;i<26;i++)
        {
            if(AC[0].vis[i]!=0)
            {
                AC[AC[0].vis[i]].fail = 0;
                Q.push(AC[0].vis[i]);
            }
        }
        while(!Q.empty())
        {
            int u = Q.front();
            Q.pop();
            for(int i=0;i<26;i++)
            {
                if(AC[u].vis[i]!=0)
                {
                    AC[AC[u].vis[i]].fail = AC[AC[u].fail].vis[i];
                    Q.push(AC[u].vis[i]);
                }
                else
                    AC[u].vis[i] = AC[AC[u].fail].vis[i];
            }
        }
    }
    int AC_Query(string s)
    {
        int l = s.length();
        int now = 0,ans = 0;
        for(int i=0;i<l;i++)
        {
            now = AC[now].vis[s[i]-'a'];
            for(int t=now;t&&AC[t].end!=-1;t=AC[t].fail)
            {
                ans += AC[t].end;
                AC[t].end = -1;
            }
        }
        return ans;
    }
    int main()
    {
        int n;
        string s;
        cin >> n;
        for(int i=1;i<=n;i++)
        {
            cin >> s;
            Build(s);
        }
        AC[0].fail = 0;
        Get_fail();
        cin >> s;
        cout << AC_Query(s) << "
    ";
    }
    
  • 相关阅读:
    NSDate 与NSString的互相转换
    NSArray 基础
    IOS 使用自定义字体
    页面跳转添加动画
    Builder 模式
    树的子结构
    Singleton 模式
    合并两个排序的链表(递归算法)
    合并两个排序的链表(非递归)
    反转链表
  • 原文地址:https://www.cnblogs.com/hh13579/p/13768835.html
Copyright © 2011-2022 走看看