摘要: 题目大意:给出N(N不超过100)个字符串, 求出最长的一个字符串, 使它是超过N / 2个字符串的子串.简要分析:显然还是可以用哈希搞, 但是哈希这种办法太落后了, 而且本身并不是个完美的算法, 因为不可能完美哈希. 于是学习了后缀数组.简单说一下后缀数组, 它把长为L的字符串的L个后缀排序了, sa[i]记录排第i名的后缀是哪一个, rank[i]记录i这个后缀的排名, height[i]记录排名为i的后缀与排名为i - 1的后缀的最长公共前缀(LCP). 这些东西的算法在论文里面都有, 详见2009年国家集训队论文集. 一个NB的结论是, 求i和j两个后缀的最长公共前缀, 不妨设rank 阅读全文
posted @ 2012-03-09 22:57 zcwwzdjn 阅读(917) 评论(0) 推荐(0) 编辑
摘要: 题目大意:求两个长度不超过100000的字符串的最长公共子串, 注意是子串而非子序列, 所以是连续的.简要分析:二分答案M, 设两个串分别为A和B, 从左到右枚举一遍A的长为M的子串, 算出哈希值丢到map里面, 再从左到右枚举一遍B的长为M的子串, 算出哈希再到map里面找. O(NlogN).代码实现:View Code 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 阅读全文
posted @ 2012-03-09 22:35 zcwwzdjn 阅读(360) 评论(0) 推荐(0) 编辑
摘要: 题目大意:给N个数, 和一个正整数K, 求出在这串数中出现过至少K次的子串的最大长度, 这里对出现的字串计数时可以重叠.简要分析:二分答案M, 然后从左到右算一遍长为M的子串的哈希值, 丢到map里面进行计数, 时间复杂度O(NlogN).代码实现:View Code 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 typedef unsigned long long ha 阅读全文
posted @ 2012-03-09 22:30 zcwwzdjn 阅读(176) 评论(0) 推荐(0) 编辑
摘要: 题目大意:给出N个数, 相邻两数做差之后, 得到N - 1个数, 求一个最大的M, 使得存在两个长为M的子串完全相同, 且两个字串不能有重叠的部分(其实还要再错开一位).简要分析:记得在USACO中做过这道题. 标准做法当然是后缀数组, 但我用哈希做的.明显答案可以二分, 二分答案M之后, 从左到右维护长为M的子串的哈希值, 并记录某个哈希值最早出现的下标位置, 这个可以用map搞. 于是就完了. 时间复杂度O(NlogN). 哈希值的算法就很多了, 只需满足一个需求, 就是在已有1..M这个子串的哈希的情况下, 能O(1)得到2..M+1的哈希值. 我用的是大质数幂取模法, 因为C语言的un 阅读全文
posted @ 2012-03-09 22:24 zcwwzdjn 阅读(326) 评论(0) 推荐(0) 编辑