[HNOI2004] L language trie tree? Ac automaton? hash! !

Title Description
appear later punctuation appears in the text, so the previous language is no punctuation. Now you have to deal with is that no punctuation section of the article.

A passage T is composed of several lower case letters. W is a word composed of a number of lower-case letters. A dictionary D is a collection of several words. We call T a passage in a dictionary D can be understood, it means that every part of the word is in the dictionary D T if the article can be divided into several parts, and.

E.g. dictionary D includes the word { 'is', 'name', 'what', 'your'}, the article 'whatisyourname' is in the dictionary D can be appreciated, because it can be divided into four words: 'what' , 'is',' your ', the' name ', and each word belongs to the dictionary D, the article' whatisyouname 'can not be understood in a dictionary D, but in the dictionary D' = D + { 'you'} being understanding. This article is a prefix 'whatis', it can also be understood in the dictionary D, and is the longest prefix in the dictionary D can be understood.

Given a dictionary D, you need to determine whether the program several sections of the article can be understood in the dictionary D. And give its location at the longest prefix dictionary D can be appreciated.

Input format
input file is the first line of two positive integers n and m, the dictionary D has n words, and there needs to be processed article segment m. After row n is described one word per line, m lines after each line describing a passage again.

Where 1 <= n, m <= 20, word length does not exceed 10 each, each length of the article does not exceed 1M.

Output format
for each input section of the article, you need to output the position of the longest prefix of this article in the dictionary D can be understood.
-------------------------------------------------- -------------------------------------------------- -----------------------------------------
emmmmmm, a lot of the magic algorithm, what KMP What the trie, what AC automaton, but will not, problem solution is not even hash, or use hash + dp, just engage in a practice of it. . .

This question is just to see when this is clearly not a hash; with s, t represent two pointers, and continuously t ++, if \ ([s, t] \) of this section to meet, put s ode to t + 1, the final output s - 1, then. . . I dropped to glorious WA. You may wish to look at this set of data:

a
abc

aabc

If using the above method, then the output value of 2, that is, match the aa, but the entire article can be translated are clearly, so greedy above idea is wrong, then how to do it. . .

First, I put the hash value of each word seek out, and then a digital hash, hash value can guarantee this within the scope of our store. I opened and a vector, q [i] denotes the end of the word i and the length of the hash value.

When matched, it \ (f [i] \) indicates whether the prefix i can match my current article from 1 to enumerate the length len, and enumerate the current hash value and the length len1 the end of the alphabet, and only when \ (f [i - len1] \) can meet, and the \ ([i - len1 + 1 , i] \) this interval is a word, then the \ (f [i] \) can be assigned to true, so that Finally, the length of the output can be achieved.

#include <bits/stdc++.h>

using namespace std;

typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 100;
const int MAXM = 5e3 + 10;
const double eps = 1e-5;

template < typename T > inline void read(T &x) {
    x = 0; T ff = 1, ch = getchar();
    while (!isdigit(ch)) {
        if (ch == '-') ff = -1;
        ch = getchar();
    }
    while (isdigit(ch)) {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    x *= ff;
}

template < typename T > inline void write(T x) {
    if (x == 0) {
        putchar('0');
        return ;
    }
    if (x < 0) putchar('-'), x = -x;
    static T tot = 0, ch[30];
    while (x) {
        ch[++tot] = x % 10 + '0';
        x /= 10;
    }
    while (tot) putchar(ch[tot--]);
} 

ull p[MAXN], vis[MAXN], sum[MAXN];
int n, m, f[MAXN];
char ch[MAXN];
const int mod = 1e6 + 7;
vector < pair < int, int > > q[30]; 

inline int H(ull x) {
    int u = x % mod;
    while (vis[u] && vis[u] != x) ++u;
    return u;
}

int main() {
    read(n), read(m);
    for (int i = 1; i <= n; ++i) {
        scanf("%s", ch + 1);
        int len = strlen(ch + 1);
        ull cnt = 0;
        for (int j = 1; j <= len; ++j) {
            cnt = cnt * 131 + ch[j] - 'a' + 1;
        }
        int u = H(cnt);
        vis[u] = cnt;
        q[ch[len] - 'a' + 1].push_back({u, len});
    }
    p[0] = 1;
    for (int i = 1; i <= MAXN; ++i) p[i] = p[i - 1] * 131;
    while (m--) {
        scanf("%s", ch + 1);
        int len = strlen(ch + 1);
        for (int i = 1; i <= len; ++i) 
            sum[i] = sum[i - 1] * 131 + ch[i] - 'a' + 1;
        f[0] = 1;
        int cnt = 0;
        for (int i = 1; i <= len; ++i) {
            f[i] = 0;
            int x = ch[i] - 'a' + 1;
            for (int j = 0; j < q[x].size(); ++j) {
                int u = q[x][j].first, len1 = q[x][j].second;
                if (i < len1) continue;
                if (!f[i - len1]) continue;
                ull v = sum[i] - sum[i - len1] * p[len1];
                int h = H(v);
                if (vis[h]) f[i] = 1, cnt = i;
            } 
        }
        write(cnt);
        puts("");
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/AK-ls/p/11787241.html
Recommended