SPOJ NSUBSTR Problem : 给一个长度为n的字符串,要求分别输出长度为1~n的子串的最多出现次数. Solution :首先对字符串建立后缀自动机,在根据fail指针建立出后缀树,对于n个后缀对应的节点打上标记,则每个结点对应的一些子串所出现的次数即为其子树内标记的个数,在后缀树上进行1遍dfs统计,之后根据答案的单调性线性扫描一遍进行统计. #include <iostream> #include <string> #include <cstring>…
SPOJ - NSUBSTR #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define PLI pair<LL, int> #define PDD pair<double,double> #define ull unsigned long long…
题意: 长度为x的本质不同的串的出现次数 题解: 先处理出每一个节点所对应的子串出现的次数 然后取max就好了 #include <set> #include <map> #include <stack> #include <queue> #include <cmath> #include <ctime> #include <cstdio> #include <string> #include <vect…
Substrings \[ Time Limit: 100ms\quad Memory Limit: 1572864 kB \] 题意 给出一个长度为 \(250000\) 的字符串,求出所有 \(x\) 的 \(F(x)\) . \(F(x)\) 含义为长度为 \(x\) 的子串出现的最多次数. 思路 先对给出的串构建后缀自动机,设 \(dp[i]\) 为后缀自动机上节点 \(i\) 包含的最长子串的出现的次数.那么对于主链的上的点,可以直接赋初始值 \(dp[i] = 1\),也就是从根节点…
Given a string, we need to find the total number of its distinct substrings. Input \(T-\) number of test cases. \(T<=20\); Each test case consists of one string, whose length is \(<=1000\) Output For each test case output one number saying the numbe…
Spoj-DISUBSTR - Distinct Substrings New Distinct Substrings SPOJ - SUBST1 我是根据kuangbin的后缀数组专题来的 这两题题意一样求解字符串中不同字串的个数: 这个属于后缀数组最基本的应用 给定一个字符串,求不相同的子串的个数. 算法分析: 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数. 如果所有的后缀按照 suffix(sa[1]), suffix(sa[2]), suffix(sa…
用后缀自动机求两个长串的最长公共子串,效果拔群.多样例的时候memset要去掉. 解题思路就是跟CLJ的一模一样啦. #pragma warning(disable:4996) #include<cstring> #include<string> #include<iostream> #include<cmath> #include<vector> #include<algorithm> #define maxn 250050 usi…
You are given a string \(S\) which consists of 250000 lowercase latin letters at most. We define \(F(x)\) as the maximal number of times that some string with length \(x\) appears in \(S\). For example for string 'ababa' \(F(3)\) will be 2 because th…
LCS - Longest Common Substring A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the set of lowercase letters. Substring, also called factor, is a consecutive sequence of characters occurrences at least on…
这里用第一个字符串构建完成后缀自动机以后 不断用第二个字符串从左往右沿着后缀自动机往前走,如能找到,那么当前匹配配数加1 如果找不到,那么就不断沿着后缀树不断往前找到所能匹配到当前字符的最大长度,然后将cur节点转移到当前节点即可,再把答案加1 记住不断更新所能得到的最大值 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace…
转载:http://hzwer.com/4492.html 给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个. 搞出后缀自动机 dp处理出每个点往下走能够走出多少个串.f[i]=sigma(f[ch[i][c])+1这个可以按Max排序之后倒着推就好了.询问的时候看一下走下去个数是否<=k,是的话就走下去,然后–k:否则就找下一条边 #include<iostream> #include<cstdio> #include<…
题意: 求多个串的最长公共子串 这里用的是O(n)的后缀自动机写法 我后缀数组的专题有nlog(n)写法的 题解: 对于其中的一个串建立后缀自动机 然后对于后缀自动机上面的每一个节点求出每一个节点最长可以匹配的子串(用maxx[]数组存下) 但是在后缀自动机上面有些节点没有走过,但是是某些走过的点的父亲节点因此也是有值的 for (int i = tot; i; i--) maxx[fail[i]] = max(maxx[fail[i]], min(len[fail[i]], maxx[i]))…
REPEATS - Repeats 链接:http://www.spoj.com/problems/REPEATS 题意:求S串中某个子串连续循环次数最多的次数. 想法: 从暴力开始,枚举所有串,求出这些串的最小循环节长度,算出连续循环次数. 如何求一个串S的最小循环节长度:即next表示这个串最长后缀与前缀相等的长度,最小循环节长度=S.length-next. KMP可以解决next,于是O(n^2)暴力求出答案.然后优化一下. 上图ans=(len+(x-y))/(x-y). 在SAM一个…
Given a string, we need to find the total number of its distinct substrings. Input T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 1000 Output For each test case output one number saying the number of distin…
705. New Distinct Substrings Problem code: SUBST1 Given a string, we need to find the total number of its distinct substrings. Input T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 50000 Output For each test…
SPOJ - SUBLEX 思路:求第k大字串,求出sam上每个节点开始能识别多少字串,然后从起点开始跑就好啦. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define PLI pair<LL, int> #define PDD pair<double…
多串的LCS,注意要利用拓扑序更新suf的len. 我用min,max,三目会超时,所以都改成了if,else #pragma warning(disable:4996) #include<cstring> #include<string> #include<iostream> #include<cmath> #include<vector> #include<algorithm> #define maxn 100050 using…
求不重复的子串个数 用所有的减去height就好了 推出来的... #include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <cctype> #include <set> #include <vector> #include <stack> #include…
因为明天要讲解后缀自动机了,所以只能抱抱佛脚,临时做做题目.其实很久以前看过,但是不太懂,看的是clj的原文,不太懂.现在只能临时看看是怎么弄的,应付下. ------------------------------------------------------------------------------------------------------------------------------ 1.自动机A为后缀自动机,A(sub) = true当且仅当sub是str的后缀. 2.一…
题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 后缀自动机的水好深啊!懂不了相关证明,带着结论把这个题做了.看来这滩深水要以后再来了. 本题要用到一个叫 Right[P] 的数组,表示 P对应的子串在原串中出现的所有位置的末尾位置下标的集合.本题中,用这个数组存储集合大小就好了,即 P对应的子串在原串中出现了Right[p]次. 而Right[P]的值,等于从改点出发到结束状态的方案数.但这个不好求,而是要用到另一个求法:用 Parent树: (暂时由…
人生第一道后缀自动机,总是值得纪念的嘛.. 后缀自动机学了很久很久,先是看CJL的论文,看懂了很多概念,关于right集,关于pre,关于自动机的术语,关于为什么它是线性的结点,线性的连边.许多铺垫的理论似懂非懂.然后看了下自动机的构造发现代码倒是挺简单,但是理解原理却是十分的困难,最后在网上找到一篇带例子的讲解帖子,我感觉算是能够说服我的吧放个链接: http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html 本题也是CLJ论文里的题,关键是如何求…
题意 给出一个字符串,要你找出所有长度的子串分别的最多出现次数. 分析 我们建出后缀自动机,然后预处理出每个状态的cnt,cnt[u]指的是u这个状态的right集合大小.我们设f[len]为长度为len的子串的最多出现次数.我们对于自动机的每个状态都更新f,f[st[u].len]=max(f[st[u].len],cnt[u]).然后这样更新完以后,可以神奇的dp一下.f[len]=max(f[len],f[len+1]).想想为什么? #include <cstdio> #include…
建后缀自动机 然后统计次数,只需要算出right集合的大小即可, 然后更新f[l[i]]和rit[i]取个max 然后根据rit集合短的一定包含长的的性质,从后往前更新一遍即可 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i)…
[SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(right/endpos\)集合的大小 那么,直接构建\(SAM\) 求出每个位置的\(right\)集合大小 直接更新每个节点的\(longest\)就行了 最后短的可以由长的更新过来就好 #include<iostream> #include<cstdio> #include<cs…
[SPOJ]Distinct Substrings(后缀自动机) 题面 Vjudge 题意:求一个串的不同子串的数量 题解 对于这个串构建后缀自动机之后 我们知道每个串出现的次数就是\(right/endpos\)集合的大小 但是实际上我们没有任何必要减去不合法的数量 我们只需要累加每个节点表示的合法子串的数量即可 这个值等于\(longest-shortest+1=longest-parent.longest\) #include<iostream> #include<cstdio&g…
http://www.spoj.com/problems/NSUBSTR/ 题意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.求F(1)..F(Length(S)) 这题做法: 首先建立字符串的后缀自动机. 所以对于一个节点$s$,长度范围为$[Min(s), Max(s)]$,出现次数是$|Right(s)|$,那么我们用$|Right(s)|$去更新$f(Max(s))$,最后用$f(i)$更新$f(i-1)$即可. #include <cstdio> #in…
传送门 后缀自动机基础题. 求长度为iii的子串出现次数的最大值. 对原串建出samsamsam,然后用sizsizsiz更新每个maxlenmaxlenmaxlen的答案. 然后由于后缀链接将其转化成了一种树形结构,因此直接在上面树形递推即可. 代码 #include<bits/stdc++.h> #define ri register int using namespace std; const int N=5e5+5; int n; char s[N]; struct SAM{ int…
后缀自动机+dp. 后缀自动机主要是在functioner大牛那里学习的:http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html 这道题是在No_stop大牛那里学习的:http://blog.csdn.net/no__stop/article/details/11784715 特别感谢这两位大牛!贴上代码作为以后的模板吧. #include<algorithm> #include<iostream> #include<cst…
You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as the maximal number of times that some string with length x appears in S. For example for string 'ababa' F(3) will be 2 because there is a string 'aba…
http://www.spoj.com/problems/SUBLEX/ 后缀自动机系列完成QAQ...撒花..明天or今晚写个小结? 首先得知道:后缀自动机中,root出发到任意一个状态的路径对应一个子串,而且不重复.(原因似乎是逆序后缀树? 所以我们在自动机上预处理每一个状态的子串数目,然后从小到大枚举字符. 子串数目可以这样预处理出:s[x]=sum{s[y]}+1, y是x出发的下一个点,意思就是说,以x开头的子串有那么多个(即将孩子的所有子串前边都加上x),然后x单独算一个子串. 然后…