那么多字串,如果暴力的会超时,看了discussion里面说是可用HASH解决的。。没想明白怎么搞,但是想到用后缀数组了。
方法是利用sa数组的特性。我们知道sa将所有后缀按照字典序大小排序,那么对于sa【i】这个后缀来说,与他lcp最大的两个后缀一定就是sa【i+1】,sa【i-1】,然后按照题目的意思要我们为每一个字符串寻找一个子串,这个子串不会出现在其他字符串中。
那么我们首相将所有字符串连城一个字符串,中间用特殊值连接,(注:不能相同)。然后记录每一个字符串开始和结束的位置。然后对于每一个字符串,我们枚举他字串开始的位置,然后通过rank数组找到相应后缀在sa数组中位置,然后分别向前,和向后找第一个不是当前字符串范围内起始的后缀,然后比较lcp取最大值加+1,最后枚举完每一个位置,获得所有最大lcp中的最小值,就是我们要找的替代子串。每一个字符串都用这种方式处理。
另外要注意的是,我们向前找向后找后缀的时候,可能会找到最后一个0值或者我们其他添加进去的特殊值,这时候要特殊处理lcp值,这里需要特殊处理LCP为1,
拎一个注意点是找到前驱后继之后求出了lcp,但是 ss[i][begin+lcp]=='\0',这说明从当前其实位置开始一直到当前字符串的结尾,都在其他字符串中出现,这是后特殊处理lcp为INF。
关于后缀数组的知识详见09年的论文http://wenku.baidu.com/view/228caa45b307e87101f696a8.html很强大的论文,看完习题刷完之后,对于后缀数组的性质,应该算是掌握了。然后就是自己的总结了。
1713. Key Substrings
Memory limit: 64 MB