Codeforces 291 E Tree-String Problem AC自动机

Tree-String Problem

网上的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\n", val[tar] - 1);
    }
} ac;

int main() {
    ac.solve();
    return 0;
}

/*
*/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/10406085.html