觉得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; }