bzoj3172 [Tjoi2013]单词

Posted 逢山开路 遇水架桥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3172 [Tjoi2013]单词相关的知识,希望对你有一定的参考价值。

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3172

【题解】

考虑建出AC自动机,那么fail树上每个点的父亲为fail,父亲->儿子为后缀关系(父亲是儿子后缀)

那么走到父亲肯定走到了儿子,直接统计即可。

技术分享
# include <queue>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 1.6e6 + 10;
const int mod = 1e9+7;

int n; char t[M];
int v[M], ps[M]; vector<int> G[M];
struct ACM {
    int ch[M][26], fail[M], siz, isend[M];
    inline void set() {siz = 0;}
    inline int ins(char *t) {
        int p = 0;
        for (int i=0; t[i]; ++i) {
            int c = t[i] - a;
            if(!ch[p][c]) ch[p][c] = ++siz;
            p = ch[p][c];
            v[p] ++;
        }
        return p;
    }
    queue<int> q;
    inline void build() {
        while(!q.empty()) q.pop();
        for (int c=0; c<26; ++c) {
            int p = ch[0][c];
            if(p) {
                fail[p] = 0;
                q.push(p);
            }
        }
        while(!q.empty()) {
            int top = q.front(); q.pop();
            for (int c=0; c<26; ++c) {
                int p = ch[top][c];
                if(!p) {
                    ch[top][c] = ch[fail[top]][c];
                    continue;
                }
                q.push(p);
                int v = fail[top];
                while(v && !ch[v][c]) v = fail[v];
                fail[p] = ch[v][c];
            }
        }
    }
    inline void getfail() {
        for (int i=1; i<=siz; ++i) 
            G[fail[i]].push_back(i);
    }
}S;

inline void dfs(int x) {
    for (int i=0; i<G[x].size(); ++i) {
        int y = G[x][i];
        dfs(y);
        v[x] += v[y];
    }
}

int main() {
    cin >> n; S.set();
    for (int i=1; i<=n; ++i) {
        scanf("%s", t);
        ps[i] = S.ins(t);
    }
    S.build();
    S.getfail();
    dfs(0);
    for (int i=1; i<=n; ++i) printf("%d\n", v[ps[i]]);
    return 0;
}
View Code

以上是关于bzoj3172 [Tjoi2013]单词的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 3172 [Tjoi2013]单词(fail树,DP)

[Bzoj3172][Tjoi2013]单词(fail树)

bzoj3172 [Tjoi2013]单词

BZOJ 3172 [Tjoi2013]单词

bzoj 3172: [Tjoi2013]单词

BZOJ-3172: [Tjoi2013]单词 (AC自动姬)