码迷,mamicode.com
首页 > 其他好文 > 详细

【模板】AC自动机

时间:2019-01-26 17:53:40      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:tmp   运算符   reg   open   stdin   --   name   ems   sigma   

自适应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;
}
 

【模板】AC自动机

标签:tmp   运算符   reg   open   stdin   --   name   ems   sigma   

原文地址:https://www.cnblogs.com/winlere/p/10324288.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!