• 【模板】AC自动机


    自适应AC自动机!

    其实就是重载运算符。

    感觉别人写的自动机下标之间太多累赘的东西,不如重载运算符。方便编写。

    实际上AC自动机就是字典树加上(kmp)算法的精髓,可以对于一个文本串快速匹配多个模式串。时间复杂度(O(Sigma n+m))

    #include<bits/stdc++.h>
    
    #define RP(t,a,b) for(register int (t)=(a),edd_=(b);t<=edd_;++t)
    #define DRP(t,a,b) for(register int (t)=(a),edd_=(b);t>=edd_;--t)
    #define ERP(t,a) for(int t=head[a];t;t=e[t].nx)
    #define Max(a,b) ((a)<(b)?(b):(a))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define pushup(x) seg[(x)]=seg[(x)<<1]+seg[(x)<<1|1]
    #define midd register int mid=(l+r)>>1
    #define chek if(R<l||r<L)return
    #define TMP template<class ccf>
    #define rgt L,R,mid,r,pos<<1|1
    #define lef L,R,l,mid,pos<<1
    #define all 1,n,1
    using namespace std;typedef long long ll;
    
    TMP inline ccf qr(ccf k){
        char c=getchar();
        ccf x=0;
        int q=1;
        while(c<48||c>57)q=c==45?-1:q,c=getchar();
        while(c>=48&&c<=57)x=x*10+c-48,c=getchar();
        return q==-1?-x:x;
    }
    
    const int maxn=1e6+5;
    string str;
    struct node{
        int son[27];
        int fail;
        int cnt;
        node(){fail=cnt=0,memset(son,0,sizeof son);}
        inline int& operator [](char x){
    	return son[x-'a'+1];
        }
        inline int& operator [](int x){
    	return son[x];
        }
        inline int operator ++(void){
    	return this->cnt=this->cnt+1;
        }
    }ac[maxn];
    int act;
    int n;
    
    inline void build(int lit){
        int now=0;
        RP(t,0,lit-1){
    	if(!ac[now][str[t]])
    	    ac[now][str[t]]=++act;
    	now=ac[now][str[t]];
        }
        ++ac[now];
    }
    
    queue< int > q;
    inline void gen(){
        RP(t,1,26)
    	if(ac[0][t])
    	q.push(ac[0][t]);
        while(q.size()){
    	int now=q.front();
    	q.pop();
    	RP(t,1,26){
    	    if(ac[now][t]){
    		ac[ac[now][t]].fail=ac[ac[now].fail][t];
    		q.push(ac[now][t]);
    	    }
    	    else
    		ac[now][t]=ac[ac[now].fail][t];
    	}
        }
    }
    
    
    inline int match(int lit){
        int ret=0,pos=0;
        for(int k=0;k<lit;++k){
    	pos=ac[pos][str[k]];
    	for(int t=pos;t&&ac[t].cnt!=-1;t=ac[pos].fail)
    	    ret+=ac[t].cnt,ac[t].cnt=-1;
        }
        return ret;
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        n=qr(1);
        while(n--)cin>>str,build(str.length());
        gen();
        cin>>str;
        cout<<match(str.length())<<endl;
        return 0;
    }
     
    
    
  • 相关阅读:
    Android 通过广播来异步更新UI
    自拉ADSL网线搭建站点server,解决动态IP、无公网IP、80port被封、HTTP被屏蔽的方法
    UVA 10494 (13.08.02)
    直线向量方程
    直线向量方程
    初等解析几何
    初等解析几何
    算法/机器学习算法工程师笔试题
    算法/机器学习算法工程师笔试题
    Python 库的使用 —— dis
  • 原文地址:https://www.cnblogs.com/winlere/p/10324288.html
Copyright © 2020-2023  润新知