• AC自动机(模板) LUOGU P3808


    传送门

    解题思路

    AC自动机,是解决多模匹配问题的算法,是字典树与kmp结合的算法,可以解决许多子串在文本串中出现的次数等信息。关键是实现一个fail指针,是指向更靠上的前缀相同字母,从而可以实现在文本串中跳的操作。

    代码

        #include<iostream>
        #include<cstdio>
        #include<algorithm>
        #include<cstring>
        #include<queue>
    
        using namespace std;
        const int MAXN = 1e6+5;
    
        int n,ans,cnt;
    
        struct Tree{
            int vis[30],fail,end;
        }AC[MAXN];
    
        inline void build(string S){
            int len=S.length();
            int now=0;
            for(register int i=0;i<len;i++){
                if(!AC[now].vis[S[i]-'a'+1])
                    AC[now].vis[S[i]-'a'+1]=++cnt;
                now=AC[now].vis[S[i]-'a'+1];
            }
            AC[now].end++;
        }
    
        inline void Get_fail(){
            queue<int> Q;
            for(register int i=1;i<=26;i++)
                if(AC[0].vis[i]){
                    AC[AC[0].vis[i]].fail=0;
                    Q.push(AC[0].vis[i]);
                }
            while(Q.size()){
                int x=Q.front();Q.pop();
                for(register int i=1;i<=26;i++){
                    if(AC[x].vis[i]){   //如果这个字母存在,子节点fail指针指向它上一层这个字母的fail所指向的字母,有点难理解,要画图
                        AC[AC[x].vis[i]].fail=AC[AC[x].fail].vis[i];
                        Q.push(AC[x].vis[i]);
                    }
                    else AC[x].vis[i]=AC[AC[x].fail].vis[i];
                }
            }
        }
    
        inline int Query(string S){
            int len=S.length();
            int now=0,t;
            for(register int i=0;i<len;i++){
                now=AC[now].vis[S[i]-'a'+1];
                for(t=now;t && AC[t].end!=-1;t=AC[t].fail){
                    ans+=AC[t].end;
                    AC[t].end=-1;
                }
            }
            return ans;
        }
    
        int main(){
            cin>>n;
            for(register int i=1;i<=n;i++){
                string s;
                cin>>s;
                build(s);
            }
            AC[0].fail=0;
            Get_fail();
            string s;
            cin>>s;
            cout<<Query(s)<<endl;
            return 0;
        }
  • 相关阅读:
    WIN8.1优化
    Iframe跨域嵌入页面自动调整高度的办法
    win8优化
    160多条Windows 7 “运行”命令
    用 C# 代码如何实现让你的电脑关机,重启,注销,锁定,休眠,睡眠
    system32下 exe文件作用
    html高度百分比分配
    Django启程篇
    自适应网页前端设计相关
    crontab定时任务及jar包等问题
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9676953.html
Copyright © 2020-2023  润新知