AC自動機(簡單版)
阿新 • • 發佈:2018-01-25
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自動機(簡單版)