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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【AC自动机】AC自动机(二次加强版)(luogu 5357)

發布時間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【AC自动机】AC自动机(二次加强版)(luogu 5357) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

luogu 5357


題目大意

給你若干單詞和一個字符串,讓你查詢每個單詞在字符串中出現的次數


解題思路

AC自動機模板

先把單詞丟進去,然后拿字符串去跑,每到一個點累計答案

因為數據較大,所以要先存起來,跑完后按照bfs的倒敘傳遞答案


代碼

#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 200021 using namespace std; int n, w, hd, tl, d[N], v[N], a[N], b[N], nx[N], to[N][30]; char s[N], ss[N*10]; int insert(char* s) {int n = strlen(s+1), now = 0;for (int i = 1; i <= n; ++i){int y = s[i] - 'a';if (!to[now][y]) to[now][y] = ++w;now = to[now][y];}return now; } void bfs() {hd = tl = 0;for (int i = 0; i < 26; ++i)if (to[0][i]) d[++tl] = to[0][i];while(hd < tl){int h = d[++hd];for (int i = 0; i < 26; ++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 n = strlen(s+1), now = 0;for (int i = 1; i <= n; ++i){int y = s[i]- 'a';now = to[now][y];b[now]++;//記錄答案}return; } int main() {scanf("%d", &n);for (int i = 1; i <= n; ++i){scanf("%s", s+1);v[i] = insert(s);}bfs();scanf("%s", ss+1);ask(ss);for (int i = tl; i > 0; --i)//傳遞答案{int x = d[i];a[x] = b[x];b[nx[x]] += b[x];}for (int i = 1; i <= n; ++i)printf("%d\n", a[v[i]]);return 0; }

總結

以上是生活随笔為你收集整理的【AC自动机】AC自动机(二次加强版)(luogu 5357)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。