日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【AC自动机】前缀匹配(ybtoj AC自动机-3)

發(fā)布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【AC自动机】前缀匹配(ybtoj AC自动机-3) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

正題

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

總結(jié)

以上是生活随笔為你收集整理的【AC自动机】前缀匹配(ybtoj AC自动机-3)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。