Topic link "http://www.lydsy.com/JudgeOnline/problem.php?id=1212"
Test instructions: Give you some words, and then give a text string with no punctuation, all lowercase characters. Now let's ask you to make a text string T with the given word, and ask for the longest common prefix of s and T.
Puzzle: AC automata + backpack, backpack dp[i], indicates whether the length of the "1,i" prefix, maintenance in the automaton Len[i], the node I to the root node distance, End[i], node I is the end of a word. In the query, we only need to jump on the corresponding trie, the time complexity of X * N*log (N).
#include <bits/stdc++.h>using namespace Std;const int maxn = 1024x768 * 1024x768 + 15;int dp[maxn];struct aho_c{int next[ MAXN][26], FAIL[MAXN], END[MAXN], LEN[MAXN]; int root, SZ; int NewNode () {for (int i = 0; i <; i++) next[sz][i] = 1; end[sz++] = 0; return sz-1; } void Init () {sz = 0; root = NewNode (); } void Insert (char buf[]) {int len = strlen (BUF); int now = root; for (int i = 0; i < len; i++) {if (Next[now][buf[i]-' a '] = =-1) next[now][buf[i]-' A '] = NewNode (); now = next[now][buf[i]-' a ']; Len[now] = i + 1; } end[now]++; } void Build () {queue<int>q; Fail[root] = root; for (int i = 0; i < i++) if (next[root][i] = = 1) next[root][i] = root; else {Fail[next[root][i]] = root; Q.push (NeXt[root][i]); } while (! Q.empty ()) {int now = Q.front (); Q.pop (); for (int i = 0; i < i++) if (next[now][i] = = 1) next[now][i] = Next[fail[now]][i]; else {Fail[next[now][i]] = next[fail[now]][i]; Q.push (Next[now][i]); }}} void Query (char buf[]) {int len = strlen (buf + 1); int now = root; for (int i = 1; I <= len; i++) {dp[i] = 0; now = next[now][buf[i]-' a ']; int temp = now; int tmp = len[temp]; while (temp! = root) {if (end[temp]) {int pos = i-len[temp] ; Dp[i] = max (Len[temp] + Dp[pos], dp[i]); } temp = fail[temp]; }}}} Ac;char Buf[maxn * 2];int main () {int N, M; scanf ("%d%d", &n, &m); Ac.init (); for (int i = 1; I <= N; i++) {scanf ("%s", buf); Ac. Insert (BUF); } AC. Build (); for (int i = 1; I <= M; i++) {scanf ("%s", buf + 1); Ac. Query (BUF); int len = strlen (buf + 1); int ma = 0; for (int i = len; I >= 1; i--) {if (dp[i] = = i) {ma = i; Break }} printf ("%d\n", MA); } return 0;}
Bzoj 1212 [hnoi2004]l language "AC automata + backpack"