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

    Miku

    简单版就是个单纯的模板

    ac自动机是啥,就是一个加了类似于kmp的next数组的tire树

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    struct t{
    	int fail;
    	int nex[26];
    	int end;
    }ac[1000001];
    int cnt;
    int l;
    int p;
    int x;
    int ans;
    int n;
    string s;
    queue <int>q;
    void build(string s){
    	l=s.length();
    	p=0;
    	for(int i=0;i<l;++i){
    		x=s[i]-'a';
    		if(!ac[p].nex[x]){
    			cnt++;
    			ac[p].nex[x]=cnt;
    		}
    		p=ac[p].nex[x];
    	}
    	ac[p].end+=1;//这就是个tire树 
    }
    void buildfail(){//找指针要 bfs 
    	ac[0].fail=0;//0指自己 
    	for(int i=0;i<26;++i){
    		if(ac[0].nex[i]!=0){
    			ac[ac[0].nex[i]].fail=0;
    			q.push(ac[0].nex[i]);
    		}//第二层也是 
    	}
    	while(!q.empty()){
    		x=q.front();
    		q.pop();
    		for(int i=0;i<26;++i){
    			if(ac[x].nex[i]!=0){
    				ac[ac[x].nex[i]].fail=ac[ac[x].fail].nex[i];//失配指针寻找
    				//为它失配指针指向的点的对应字母 
    				q.push(ac[x].nex[i]);//改了就压,继续更新 
    			}else{
    				ac[x].nex[i]=ac[ac[x].fail].nex[i];//如果这个点是不存在的
    				//那么直接指向失配指针对应点的对应点 
    			}
    		}	
    	}
    }
    int query(string s){
    	l=s.length();
    	p=0;
    	ans=0;
    	for(int i=0;i<l;++i){
    		x=s[i]-'a';
    		p=ac[p].nex[x];
    		for(int j=p;j&&ac[j].end!=-1;j=ac[j].fail){//跳跃,收集,清空 
    			ans+=ac[j].end;
    			ac[j].end=-1;
    		}
    	}
    	return ans;
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i){
    		cin>>s;
    		build(s);
    	}
    	buildfail();
    	cin>>s;
    	cout<<query(s)<<endl;
    	return 0;
    } 
    
  • 相关阅读:
    EVM靶机渗透
    Joomla漏洞复现
    渗透测试
    Kali软件库认识
    谷歌hack语法
    Metasploit学习
    sqli-labs less-17
    sqli-labs(less-11-16)
    sqli-labs (less-8-less-10)
    less-7
  • 原文地址:https://www.cnblogs.com/For-Miku/p/13429763.html
Copyright © 2011-2022 走看看