网上的dfs + kmp 复杂度就是错的, 除非算出根据下一个字符直接转移Next数组直接转移, 而求出Next[ i ][ 26 ]数组和丢进AC自动机里面没有区别。。
然后我的AC自动机还写麻烦了。。 我把全部都求进去求fail然后沿着fail推到目标串, 好蠢啊啊。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 5e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; int n, p[N]; string s[N], t; vector<int> G[N]; vector<int> vc; struct Ac { int ch[N][26], f[N], tot, sz; int tar; LL val[N]; inline int newNode() { tot++; f[tot] = 0; val[tot] = 0; memset(ch[tot], 0, sizeof(ch[tot])); return tot; } void init(int _sz) {sz = _sz; tot = -1; newNode();} inline int idx(int c) {return c - 'a';} void addStr(string& s) { int u = 0; for(int i = 0; i < SZ(s); i++) { int c = idx(s[i]); if(!ch[u][c]) ch[u][c] = newNode(); u = ch[u][c]; val[u]++; } tar = u; } void build() { queue<int> que; for(int c = 0; c < sz; c++) { int v = ch[0][c]; if(!v) ch[0][c] = 0; else f[v] = 0, que.push(v), vc.push_back(v); } while(!que.empty()) { int u = que.front(); que.pop(); for(int c = 0; c < sz; c++) { int v = ch[u][c]; if(!v) ch[u][c] = ch[f[u]][c]; else f[v] = ch[f[u]][c], que.push(v), vc.push_back(v); } } for(int i = SZ(vc) - 1; i >= 0; i--) val[f[vc[i]]] += val[vc[i]]; } void dfs(int x, int pos) { for(auto& y : G[x]) { int u = pos; for(int i = 0; i < SZ(s[y]); i++) { int c = idx(s[y][i]); if(!ch[u][c]) ch[u][c] = newNode(); u = ch[u][c]; val[u]++; } dfs(y, u); } } void solve() { init(26); cin >> n; for(int i = 2; i <= n; i++) { cin >> p[i] >> s[i]; G[p[i]].push_back(i); } cin >> t; addStr(t); dfs(1, 0); build(); printf("%lld ", val[tar] - 1); } } ac; int main() { ac.solve(); return 0; } /* */