• [模板]AC自动机


    https://blog.csdn.net/creatorx/article/details/71100840
    AC自动机就是一直跳fail边,然后找到整个要匹配的串就行了。
    fail边:大概就是指向以当前节点表示的字符 为最后一个字符的 最长当前字符串的 后缀字符串的 最后一个节点(摘自上面的博客并断句
    代码:luogu3808

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    int n;
    const int N=500010;
    struct ACZDJ {
    	int tr[N][26],fail[N],val[N],cnt;
    	void insert(char *s) {
    		int len=strlen(s),p=0;
    		for(int i=0; i<len; i++) {
    			if(!tr[p][s[i]-'a']) tr[p][s[i]-'a']=++cnt;
    			p=tr[p][s[i]-'a'];
    		}
    		val[p]++;
    	}
    	void build() {
    		queue<int>q;
    		for(int i=0; i<26; i++)
    			if(tr[0][i]) q.push(tr[0][i]),fail[tr[0][i]]=0;
    		while(!q.empty()) {
    			int u=q.front();
    			q.pop();
    			for(int i=0; i<26; i++) {
    				if(tr[u][i]) q.push(tr[u][i]),fail[tr[u][i]]=tr[fail[u]][i];
    				else tr[u][i]=tr[fail[u]][i];
    			}
    		}
    	}
    	int query(char *s) {
    		int len=strlen(s),p=0,ans=0;
    		for(int i=0; i<len; i++) {
    			int v=s[i]-'a';
    			p=tr[p][v];
    			for(int j=p; ~val[j]&&j; j=fail[j]) {
    				ans+=val[j];
    				val[j]=-1;
    			}
    		}
    		return ans;
    	}
    } AC;
    char s[2000005];
    int main() {
    	scanf("%d",&n);
    	while(n--) {
    		scanf("%s",s);
    		AC.insert(s);
    	}
    	AC.build();
    	scanf("%s",s);
    	cout<<AC.query(s);
    }
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    CentOS6.5配置网络
    php curl 总结
    laravel-5-doctrine-2 教程
    DOS 总结
    Centos如何通过yum安装php7
    sql with 写法
    php 汉字转拼音函数
    MYSQL 升序排序但值为0的排最后
    zookeeper基础知识
    初识redis
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9314832.html
Copyright © 2020-2023  润新知