单词

洛谷-P3966-单词open in new window

实现

#include <iostream>
#define null 0
using namespace std;

const int N = 210, M = 1000010;
int n;
char str[M];
int idx, trie[M][26], f[M], fail[M], root = 0;
int rec[N];
int h = 1, t, q[M];

void insert (int k) {
    int ptr = root;
    for (int i = 1; str[i]; ++ i) {
        int ch = str[i] - 'a';
        if (trie[ptr][ch] == null) trie[ptr][ch] = ++ idx;
        ptr = trie[ptr][ch];
        ++ f[ptr];
    }
    rec[k] = ptr;
}
void build () {
    for (int i = 0; i < 26; ++ i)
        if (trie[root][i] != null)
            q[++ t] = trie[root][i];
    while (h <= t) {
        int cur = q[h ++];
        for (int i = 0; i < 26; ++ i) {
            int ptr = trie[cur][i];
            if (ptr == null) {
                trie[cur][i] = trie[fail[cur]][i];
            } else {
                fail[ptr] = trie[fail[cur]][i];
                q[++ t] = ptr;
            }
        }
    }
}

int main () {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++ i) {
        scanf("%s", str + 1);
        insert(i);
    }

    build();
    for (int i = idx; i >= 2; -- i)
        f[fail[q[i]]] += f[q[i]];
    for (int i = 1; i <= n; ++ i)
        printf("%d\n", f[rec[i]]);
    return 0;
}
最后修改于: