AC自动机 板子
在Trie上做KMP
https://www.luogu.org/problemnew/show/3808
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | #include<cstdio> #include<queue> #include<iostream> #define FOR(i,s,t) for(register int i=s;i<=t;++i) using std::cin; const int N=4000011; char s[N]; int tot,n,ans; namespace AC_automaton{ struct Tire{ int cnt,fail; int to[27]; }tr[N]; inline void build_tire(){ int u=0; for (register int i=0;s[i]!= '\0' ;++i){ if (!tr[u].to[s[i]- 'a' ]) tr[u].to[s[i]- 'a' ]=++tot; u=tr[u].to[s[i]- 'a' ]; } ++tr[u].cnt; } inline void build_automaton(){ int v,u; std::queue< int >q; FOR(i,0,25) if ((v=tr[0].to[i])) q.push(v); int now; while (!q.empty()){ now=q.front();q.pop(); FOR(i,0,25){ v=tr[now].to[i]; u=tr[now].fail; if (v){ tr[v].fail=tr[u].to[i]; q.push(v); } else tr[now].to[i]=tr[u].to[i]; } } } inline void match(){ int now=0,tmp; for (register int i=0;s[i]!= '\0' ;++i){ now=tr[now].to[s[i]- 'a' ]; tmp=now; while (tmp&&tr[tmp].cnt!=-1){ ans+=tr[tmp].cnt; tr[tmp].cnt=-1; tmp=tr[tmp].fail; } } } } using namespace AC_automaton; int main(){ scanf( "%d\n" ,&n); while (n--){ scanf( "%s" ,s); build_tire(); } tr[0].fail=0; build_automaton(); scanf( "%s" ,s); match(); printf( "%d\n" ,ans); return 0; } |
https://www.luogu.org/problemnew/show/3796
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | #include<cstdio> #include<queue> #define FOR(i,s,t) for(register int i=s;i<=t;++i) const int N=1000011; std::queue< int >q; namespace AC_automaton{ int ans[155]; char s[233][233]; char A[N]; struct Tire{ int fail; int to[26]; int pos; inline void init(){ fail=pos=0; FOR(i,0,25)to[i]=0; } }tr[N]; int tot; inline void insert( char *s, int pos){ int u=0,v; for (register int i=0;s[i]!= '\0' ;++i){ if (!tr[u].to[s[i]- 'a' ]) tr[tr[u].to[s[i]- 'a' ]=++tot].init(); u=tr[u].to[s[i]- 'a' ]; } tr[u].pos=pos; } inline void build_fail(){ int u,v,now; FOR(i,0,25) if ((u=tr[0].to[i])){ tr[u].fail=0; q.push(u); } while (!q.empty()){ now=q.front();q.pop(); FOR(i,0,25){ v=tr[now].to[i]; u=tr[now].fail; if (v){ tr[v].fail=tr[u].to[i]; q.push(v); } else tr[now].to[i]=tr[u].to[i]; } } } inline void match( char *s){ int now=0,tmp; for (register int i=0;s[i]!= '\0' ;++i){ now=tr[now].to[s[i]- 'a' ]; tmp=now; while (tmp){ ++ans[tr[tmp].pos]; tmp=tr[tmp].fail; } } } } using namespace AC_automaton; int n,mx; int main(){ while (~scanf( "%d" ,&n)&&n){ FOR(i,0,n) ans[i]=0; tot=0; tr[0].fail=0; tr[0].init(); FOR(i,1,n){ scanf( "%s" ,s[i]); insert(s[i],i); } build_fail(); scanf( "%s" ,A); match(A); ans[0]=0; mx=1; FOR(i,1,n) if (ans[mx]<ans[i]) mx=i; printf( "%d\n" ,ans[mx]); FOR(i,1,n) if (ans[mx]==ans[i]) printf( "%s\n" ,s[i]); } return 0; } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步