【AC自动机】单词(luogu 3966/ybtoj AC自动机-2)
生活随笔
收集整理的這篇文章主要介紹了
【AC自动机】单词(luogu 3966/ybtoj AC自动机-2)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
luogu 3966
ybtoj AC自動機-2
題目大意
給你n個單詞,讓你查詢這寫單詞分別在這n個單詞中出現過多少次
解題思路
先用AC自動機建好圖,然后每個點的權值為1,然后向nx傳遞
代碼
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 1000100 using namespace std; int n, w, hd, tl, d[N], v[N], a[N], b[N], nx[N], to[N][30]; char s[N]; 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];b[now]++;//權值為1}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; } int main() {scanf("%d", &n);for (int i = 1; i <= n; ++i){scanf("%s", s+1);v[i] = insert(s);}bfs();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自动机】单词(luogu 3966/ybtoj AC自动机-2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开学装机不上当,两大平台主板选购指导请收
- 下一篇: 【AC自动机】前缀匹配(ybtoj AC