POJ 3415 (后缀自动机)】的更多相关文章

POJ 3415 Common Substrings Problem : 给两个串S.T (len <= 10^5), 询问两个串有多少个长度大于等于k的子串(位置不同也算). Solution :最开始的想法是将S串和T串先后插入后缀自动机,统计出每个节点对应串的出现次数,不过这种做法被卡空间了. 第二种想法是只将S串插入后缀自动机,建立后缀树,统计出每个节点对应串的出现次数,在统计出每个节点的所有父亲节点的出现次数之和.之后将T串在后缀自动机上进行匹配,假设当前T串在p节点匹配成功,且匹配成…
题目链接:http://poj.org/problem?id=3415 题意:给定2个串[A串和B串],求两个串公共子串长度大于等于k的个数. 思路:首先是两个字符串的问题.所以想用一个'#'把两个字符串拼接起来.求后缀数组. 然后按照k把height数组分组.大于等于k的为一组,然后就是统计每组的贡献.对于每一组的贡献即是组内所有A串的后缀和B串的后缀的lcp值,即为val.那么val对于答案的贡献为(val-k+1).如果我们暴力每组的AB串后缀的组合.时间复杂度是O(n^2).不能满足要求…
POJ 3518 Boring Problem : 给一个串S,询问串S有多个子串出现至少两次且位置不重叠. Solution : 对S串建立后缀自动机,再建立后缀树,dfs一遍统计处每个结点的子树中最长节点max和最短节点min.枚举一遍后缀自动机的节点,那么对于其对应后缀的长度要求为小于等于max - min. #include <iostream> #include <algorithm> using namespace std; const int N = 1000008;…
POJ - 2774: 题意: 求解A,B串的最长公共字串 (摘自罗穗骞的国家集训队论文): 算法分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长 公共子串等价于求 A 的后缀和 B 的后缀的最长公共前缀的最大值. 如果枚举 A 和 B 的所有的后缀,那么这样做显然效率低下. 由于要计算 A 的后缀和 B 的后缀 的最长公共前缀, 所以先将第二个字符串写在第一个字符串后面,中间用一个没 有出现过的字符隔开, 再求这个新的字符串的后缀数组.观察一下,看看能不能从…
Common Substrings Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 11469   Accepted: 3796 Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤i+k-1≤|T|. Given two strings A, B and one integer K, we define S,…
POJ - 1743 顺着原字符串找到所有叶子节点,然后自下而上更新,每个节点right的最左和最右,然后求出答案. #include<cstdio> #include<cstring> #include<algorithm> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define PLI p…
题目大意: 给定A,B两种字符串,问他们当中的长度大于k的公共子串的个数有多少个 这道题目本身理解不难,将两个字符串合并后求出它的后缀数组 然后利用后缀数组求解答案 这里一开始看题解说要用栈的思想,觉得很麻烦就不做了,后来在比赛中又遇到就后悔了,到今天看了很久才算看懂 首先建一个栈,从栈底到栈顶都保证是单调递增的 我们用一个tot记录当前栈中所有项和一个刚进入的子串匹配所能得到的总的子串的数目(当然前提是,当前进入的子串height值比栈顶还大,那么和栈中任意一个子串匹配都保持当前栈中记录的那时…
Common Substrings \[ Time Limit: 5000 ms\quad Memory Limit: 65536 kB \] 题意 给出两个字符串,要求两个字符串公共子串长度不小于 \(k\) 的对数. 思路 对 \(S\) 串构建后缀自动机,然后利用 \(v \in u'son\),\(dp[u] += dp[v]\) 求出每个节点的 \(endpos\) 大小. 用 \(T\) 串在自动机上跑最长公共连续子串,假设现在在 \(T\) 串上匹配的最长部分是 \(t\),停在自…
http://poj.org/problem?id=1509 后缀自动机其实就是一个压缩储存空间时间(对节点重复利用)的储存所有一个字符串所有子串的trie树,如果想不起来长什么样子可以百度一下找个图回忆,从0开始到任意一个点的串都是字符串的子串. 有一些很好用的性质. 字符串的最小表示就是把一个字符串首尾相连再从任意一个地方断开产生的字典序最小的字符串,这个题是求最小表示的开头字母在原字符串中的下标(从1开始). 具体看实现吧,没什么可以解释的地方. #include<iostream> #…
题意: 给两个串\(A.B\),问你长度\(>=k\)的有几对公共子串 思路: 先想一个朴素算法: 把\(B\)接在\(A\)后面,然后去跑后缀数组,得到\(height\)数组,那么直接\(rmq\)就能\(O(1)\)得到任意两个\(A\)和\(B\)的LCP.如果\(LCP >= k\),那么这个串的贡献对数为\(LCP - k + 1\).但是这样遍历显然超时. 那么我们可以用单调栈优化这个问题: 我们构建一个递增的单调栈,那么栈顶就是最大,每个栈里的元素为贡献值\(height\)的…