SPOJ NSUBSTR Substrings】的更多相关文章

人生第一道后缀自动机,总是值得纪念的嘛.. 后缀自动机学了很久很久,先是看CJL的论文,看懂了很多概念,关于right集,关于pre,关于自动机的术语,关于为什么它是线性的结点,线性的连边.许多铺垫的理论似懂非懂.然后看了下自动机的构造发现代码倒是挺简单,但是理解原理却是十分的困难,最后在网上找到一篇带例子的讲解帖子,我感觉算是能够说服我的吧放个链接: http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html 本题也是CLJ论文里的题,关键是如何求…
题意 dt { font-weight: bold; margin-top: 20px; padding-left: 35px; } dd { box-shadow: 3px 3px 6px #888888; background-color: rgba(210, 210, 255, 0.5); padding: 20px; -moz-border-radius: 10px; -webkit-border-radius: 10px; font-family: "Merriweather"…
建后缀自动机 然后统计次数,只需要算出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)…
先求个SAM,然后再每个后缀的对应点上标记si[nw]=1,造好SAM之后用吧parent树建出来把si传上去,然后用si[u]更新f[max(u)],最后用j>i的[j]更新f[i] 因为每个点u对应长为min(u)~max(u)的串,我们就把它记在max(u)上,最后再统一向前更新,然后更新后的si就表示right大小,也就是这个串对应的后缀个数 #include<iostream> #include<cstdio> #include<cstring> usi…
spoj 8222 Substrings 题意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.求F(1)..F(Length(S)) 解题思路:我们构造S的SAM,那么对于一个节点s,它的长度范围是[Min(s),Max(s)],同时他的出现次数是|Right(s)|.那么我们用|Right(s)|去更新F(Max(s))的值.那么现在的问题是如何快速求 |right(s)| 了还记得论文里parent tree吗?看看那个就知道了,不懂可以留言.接下来还有一步,我们…
[SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(right/endpos\)集合的大小 那么,直接构建\(SAM\) 求出每个位置的\(right\)集合大小 直接更新每个节点的\(longest\)就行了 最后短的可以由长的更新过来就好 #include<iostream> #include<cstdio> #include<cs…
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…
SPOJ NSUBSTR Problem : 给一个长度为n的字符串,要求分别输出长度为1~n的子串的最多出现次数. Solution :首先对字符串建立后缀自动机,在根据fail指针建立出后缀树,对于n个后缀对应的节点打上标记,则每个结点对应的一些子串所出现的次数即为其子树内标记的个数,在后缀树上进行1遍dfs统计,之后根据答案的单调性线性扫描一遍进行统计. #include <iostream> #include <string> #include <cstring>…
题链: http://www.spoj.com/problems/NSUBSTR/题解: 后缀自动机. 不难发现,对于自动机里面的一个状态s, 如果其允许的最大长度为maxs[s],其right集合的大小为right[s], 那么显然就可能对ANS[maxs[s]]造成贡献,即ANS[maxs[s]]=max(ANS[maxs[s]],right[s]) 最后再反向扫一遍ANS数组,从后向前取max即可. 那么现在的问题就是如何求得right[]数组,即如何求出每个状态的right集合的大小.…
题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 同届红太阳 --WSY给出的后缀数组解法!!! 首先用倍增算法求出 sa[i],rak[i],hei[i]然后维护出 L[i]数组表示:在后缀数组中,排名最小(记其排名为 L[i])的后缀与排名i的后缀的LCP>=hei[i]同理,R[i]数组表示:在后缀数组中,排名最大(记其排名为 R[i])的后缀与排名i的后缀的LCP>=hei[i]以上两个数组可以由单调栈 O(N)维护出来. 然后呢,令 ANS[…