1. 程式人生 > >AC自動機(簡單版)

AC自動機(簡單版)

log ble mes i++ ++ printf family 16px pre

覺得AC自動機怪簡單是怎麽回事?(可能題太裸了)

原題鏈接:https://www.luogu.org/problemnew/show/P3808

網上講AC自動機和tire樹講的比我好的dalao數不勝數,我就不多贅述了,權當是掛個板子吧。

其實char和strlen還是挺好用的。

#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
struct tire
{
    int fail;
    int vis[33];
    int end;
}tr[1000000];
int cnt=0
,n; char s[1000005]; void build(char s[]) { int len=strlen(s); int t=0; for(int i=0;i<len;i++) { if(tr[t].vis[s[i]-a]==0) tr[t].vis[s[i]-a]=++cnt; t=tr[t].vis[s[i]-a]; } tr[t].end++; } void getfail() { queue<int>q; for(int i=0;i<26;i++) {
if(tr[0].vis[i]) { tr[tr[0].vis[i]].fail=0; q.push(tr[0].vis[i]); } } while(!q.empty()) { int t=q.front();q.pop(); for(int i=0;i<26;i++) { if(tr[t].vis[i]) { tr[tr[t].vis[i]].fail=tr[tr[t].fail].vis[i]; q.push(tr[t].vis[i]); }
else tr[t].vis[i]=tr[tr[t].fail].vis[i]; } } } int query(char s[]) { int len=strlen(s); int t=0,ans=0; for(int i=0;i<len;i++) { int t=tr[t].vis[s[i]-a]; for(int j=t;j&&tr[j].end!=-1;j=tr[j].fail) { ans+=tr[j].end; tr[j].end=-1; } } return ans; } int main() { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%s",s); build(s); } tr[0].fail=0; getfail(); scanf("%s",s); printf("%d",query(s)); return 0; }

AC自動機(簡單版)