【AC自动机】AC自动机(二次加强版)(luogu 5357)
生活随笔
收集整理的這篇文章主要介紹了
【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)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iPhone15 Pro所有版本均破发
- 下一篇: 开学装机不上当,两大平台主板选购指导请收