【AC自动机】前缀匹配(ybtoj AC自动机-3)
生活随笔
收集整理的這篇文章主要介紹了
【AC自动机】前缀匹配(ybtoj AC自动机-3)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
ybtoj AC自動機-3
題目大意
給你一個字符串和若干匹配串,問你匹配串的前綴和字符串的最大匹配
解題思路
先把所有匹配串丟進AC自動機,然后拿字符串去跑
每次只在當前位置存下貢獻,然后按bfs的倒敘傳遞貢獻,最后再倒著跑每個匹配串
代碼
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 10000010 using namespace std; int n, w, hd, tl, len, q[N], b[N], d[N], v[N], nx[N], fa[N], to[N][4]; char s[N], ss[N]; int check(char g) {if (g == 'E') return 0;if (g == 'S') return 1;if (g == 'W') return 2;if (g == 'N') return 3; } int insert(char* s) {int now = 0, n = strlen(s+1);for (int i = 1; i <= n; ++i){int y = check(s[i]);if (!to[now][y]) to[now][y] = ++w;fa[to[now][y]] = now;q[to[now][y]] = q[now] + 1;now = to[now][y];}return now; } void bfs() {for (int i = 0; i < 4; ++i)if (to[0][i]) d[++tl] = to[0][i];while(hd < tl){int h = d[++hd];for (int i = 0; i < 4; ++i)if (!to[h][i]) to[h][i] = to[nx[h]][i];else nx[to[h][i]] = to[nx[h]][i], d[++tl] = to[h][i];}return; } void ask(char* s) {int now = 0;for (int i = 1; i <= len; ++i){int y = check(s[i]);now = to[now][y];b[now] = 1;}return; } int find(int x)//倒著跑匹配串 {while(x && !b[x]) x = fa[x];return q[x]; } int main() {scanf("%d%d", &len, &n);scanf("%s", ss+1);for (int i = 1; i <= n; ++i){scanf("%s", s+1);v[i] = insert(s);}bfs();ask(ss);for (int i = tl; i > 0; --i)b[nx[d[i]]] |= b[d[i]];//傳遞貢獻for (int i = 1; i <= n; ++i)printf("%d\n", find(v[i]));return 0; }總結
以上是生活随笔為你收集整理的【AC自动机】前缀匹配(ybtoj AC自动机-3)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【AC自动机】单词(luogu 3966
- 下一篇: 隐藏电脑文件如何设置电脑的隐藏