zoukankan      html  css  js  c++  java
  • 【模板】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;
    }
     
    
    
  • 相关阅读:
    在Centos 7下编译openwrt+njit-client
    开博随笔
    Chapter 6. Statements
    Chapter 4. Arrays and Pointers
    Chapter 3. Library Types
    Chapter 2.  Variables and Basic Types
    关于stm32不常用的中断,如何添加, 比如timer10 timer11等
    keil 报错 expected an identifier
    案例分析 串口的地不要接到电源上 会烧掉
    案例分析 CAN OPEN 调试记录 进度
  • 原文地址:https://www.cnblogs.com/winlere/p/10324288.html
Copyright © 2011-2022 走看看