摘要:
POJ_1204 其实POJ这个题目叙述得不太严谨,所以我就先做SPOJ上这个题去了,回来之后交了一下倒是也过了。这个题目可以用AC自动机去做,为了能够在匹配完单词后顺利找到单词首位置,我们可以选择把单词反过来建字母树,这样最后一个字符实际上就是第一个字符。 在后面查找的时候可以做一个小优化,就是找过的字典树上的结点的标记置为-1,以后再遇到这个结点就直接break而没必要再沿着预处理的标记向上寻找了。#include<stdio.h>#include<string.h>#define MAXD 800010#define MAXN 1010char b[MAXN][M 阅读全文
摘要:
HDU_2222 今天开始学AC自动机了,这个就是我AC自动机的处女作了。这个题有个小trick就是单词列表中可能有重复的单词,但这些重复的单词应看做不同的,因此建字典树时做标记的时候,把原来的赋值为1的操作变为自加1的操作即可。 最后匹配的时候有一个小优化,就是比如当前正在看有多少个以j结点的字符为结尾的单词,那么我们还需要不停地沿预处理的标记向上找,当我们找过之后就可以把当前节点的标记做成-1,以后再遇到-1的时候,就直接break,无需再沿着标记向上找了,因为上面的结点一定在之前就找过了。这个优化大概能节省400ms的时间。#include<stdio.h>#include& 阅读全文
摘要:
POJ_2752 将字符串对自己进行KMP匹配即可,也即进行一般的KMP问题的预处理的步骤。之后去找恰好匹配到最后一个字符的所有可能的前缀的长度即可,也就是遍历一遍P[N],其中N为字符串的长度。#include<stdio.h>#include<string.h>#define MAXD 400010char b[MAXD];int P[MAXD];void printresult(int k){ if(P[k] == 0) printf("%d", k); else { printresult(P[k]); printf(" %d... 阅读全文