Test instructions
Give a matching string and n words;
The maximum prefix length that each word appears in the matching string;
Match string length <=10^7,n<=10^5, Word length <=100;
Exercises
That year what will not be naïve a KMP cheated 50 points, and then see the puzzle is the automatic feeling good god ah;
Now come back to review the automatic machine to cut the problem to try;
Basic build automata what not to say;
It's mostly about the answer. I was recording an array of is on the trie tree;
Then each match string matches to the node all marked;
(Of course, this is to put a series of suffixes of the fail pointer with the same node mark)
At last, as in the accomplishment, sweep the automaton, the maximum prefix length of each word tag is the answer;
Build and find the complexity of the answer is O (100n), the self-motive match is about O (10^7) or so;
There is a small optimization, find the suffix when found already marked can be exited, because the back must also be marked to complete;
probably save 500ms;
And a little ... Because the matching string is very long, few words are very short;
So large random data can be regarded as words all in the matching string thus may deceive 4 points 233333 (Orz gaoj, thinking too God);
Code:
#include <queue> #include <stdio.h> #include <string.h> #include <algorithm> #define N 100001# Define M 10000001using namespace Std;queue<int>q;int fail[m], next[m][4], root, tot = 1;char str[m], A[n][101];bool Is[m];int F (char a) {switch (a) {case ' E ': Return 0;case ' S ': Return 1;case ' W ': Return 2;case ' N ': Return 3;}} void Insert (char *s) {int P=root,index;while (*s! = ')} {index = f (*s); if (next[p][index] = = 0) Next[p][index] = ++tot;p=ne xt[p][index];s++;}} void Build () {int p, temp, i;q.push (root), while (!q.empty ()) {p = Q.front (), Q.pop (); for (i = 0; i < 4; i++) {if (next[p][ I]) {temp = Fail[p];while (temp) {if (Next[temp][i]) {Fail[next[p][i]] = next[temp][i];break;} temp = fail[temp];} if (!temp) fail[next[p][i]] = Root;q.push (Next[p][i]);}}} void query (char *s) {int index, p, temp;p = Root;while (*s! = ') {index = f (*s); while (next[p][index] = = 0 && p) p = fail[p];p = p? Next[p][index]: root;temp = P;while (temp&&is[temp] = = 0) {Is[temp] = 1;temp = fail[TEMP];} s++;}} void Slove (char *s) {int p = root, index, ret = 0;while (*s! = ') ') {index = f (*s); if (Is[next[p][index]]) ret++;elsebreak;p = next[p][index];s++;} printf ("%d\n", ret);} int main () {int n, m, I, J, K, len;scanf ("%d%d", &len, &n), scanf ("%s", str); for (i = root = 1; I <= n; i++) {scan F ("%s", A[i]); Insert (A[i]);} Build (); query (str); for (i = 1; I <= n; i++) {slove (a[i]);} return 0;}
vijos-1951 Xuanwu Code