SPOJ NSUBSTR Substrings
题意
给出一个字符串S,令\({F(x)}\)表示S的所有长度为x的子串出现次数的最大值。求\({F(1)......F(length(S))}\)
MashiroSky的题解
另外我觉得他的总结写得也不错。
后缀自动机例题,下面写几点自己认为理解后缀自动机的重点。
- 后缀自动机相对于后缀树就是将Right集合相同的子串合用一个节点来表示。每一个节点代表一个状态S,这个状态可能包含很多长度区间连续的子串,这些子串的右端点固定,它们的Right集合相同。
- 往上跳parent的过程相当于将子串的前面一节截掉,得到一个长度更短的子串,它们的Right集合变多了。走状态转移边的过程相当于在子串的后面添加新的字符,到达新的状态。
- 构造过程中,情况一很好理解,考虑情况二和情况三的区别。情况二是parent中存在x边到达某一个状态\({V_q}\),并且这个状态的所有子串都可以接受当前插入的这个这个后缀。情况三是虽然存在状态\({V_q}\),但是这个状态所包含一部分长度比较长的的子串无法接受要插入的这个后缀,所以将它拆成两份,一份可以接受,一份不能接受。
对于这道题,我们需要做的就是计算SAM中每个节点的Right集合的大小,即在串中的出现次数。因为parent树的某个节点Right集合是它父亲的真子集,所以我们考虑从parent树的底端向上不断更新祖先的Right集合。因为len更大的节点在parent树上肯定深度更深,所以用基数排序确定拓扑序,然后更新。由于是树形结构,所以不会重复计算。
时间复杂度\(O(|S|)\)
代码
随便取个名字都重名了。
co int N=2.5e5+2;
char s[N];
int n,root,last,sz;
int ch[N*2][26],len[N*2],link[N*2];
void extend(int c){
int np=++sz,p=last;last=np;
len[np]=len[p]+1;
for(;p&&!ch[p][c];p=link[p]) ch[p][c]=np;
if(!p) link[np]=root;
else{
int q=ch[p][c];
if(len[q]==len[p]+1) link[np]=q;
else{
int nq=++sz;len[nq]=len[p]+1;
memcpy(ch[nq],ch[q],sizeof ch[q]);
link[nq]=link[q],link[np]=link[q]=nq;
for(;p&&ch[p][c]==q;p=link[p]) ch[p][c]=nq;
}
}
}
int b[N],ref[N*2],right[N*2],f[N];
int main(){
// insert
scanf("%s",s+1),n=strlen(s+1);
root=last=sz=1;
for(int i=1;i<=n;++i) extend(s[i]-'a');
// topu-sort
for(int p=root,i=1;i<=n;++i) p=ch[p][s[i]-'a'],::right[p]=1;
for(int i=1;i<=sz;++i) ++b[len[i]];
for(int i=1;i<=n;++i) b[i]+=b[i-1];
for(int i=1;i<=sz;++i) ::ref[b[len[i]]--]=i;
for(int i=sz;i>=1;--i) ::right[link[::ref[i]]]+=::right[::ref[i]];
// solve
for(int i=1;i<=sz;++i) f[len[i]]=max(f[len[i]],::right[i]);
for(int i=n;i>=1;--i) f[i]=max(f[i],f[i+1]);
for(int i=1;i<=n;++i) printf("%d\n",f[i]);
return 0;
}
SPOJ NSUBSTR Substrings的更多相关文章
- SPOJ NSUBSTR Substrings 后缀自动机
人生第一道后缀自动机,总是值得纪念的嘛.. 后缀自动机学了很久很久,先是看CJL的论文,看懂了很多概念,关于right集,关于pre,关于自动机的术语,关于为什么它是线性的结点,线性的连边.许多铺垫的 ...
- SPOJ NSUBSTR Substrings ——后缀自动机
建后缀自动机 然后统计次数,只需要算出right集合的大小即可, 然后更新f[l[i]]和rit[i]取个max 然后根据rit集合短的一定包含长的的性质,从后往前更新一遍即可 #include &l ...
- spoj NSUBSTR - Substrings【SAM】
先求个SAM,然后再每个后缀的对应点上标记si[nw]=1,造好SAM之后用吧parent树建出来把si传上去,然后用si[u]更新f[max(u)],最后用j>i的[j]更新f[i] 因为每个 ...
- spoj 8222 Substrings (后缀自动机)
spoj 8222 Substrings 题意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.求F(1)..F(Length(S)) 解题思路:我们构造S的SAM,那么对于 ...
- 【SPOJ】Substrings(后缀自动机)
[SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(rig ...
- SPOJ - NSUBSTR 后缀自动机板子
SPOJ - NSUBSTR #include<bits/stdc++.h> #define LL long long #define fi first #define se second ...
- SPOJ NSUBSTR (后缀自动机)
SPOJ NSUBSTR Problem : 给一个长度为n的字符串,要求分别输出长度为1~n的子串的最多出现次数. Solution :首先对字符串建立后缀自动机,在根据fail指针建立出后缀树,对 ...
- ●SPOJ 8222 NSUBSTR–Substrings
题链: http://www.spoj.com/problems/NSUBSTR/题解: 后缀自动机. 不难发现,对于自动机里面的一个状态s, 如果其允许的最大长度为maxs[s],其right集合的 ...
- ●SPOJ 8222 NSUBSTR - Substrings(后缀数组)
题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 同届红太阳 --WSY给出的后缀数组解法!!! 首先用倍增算法求出 sa[i],rak[i],hei[i]然 ...
随机推荐
- SpringBoot document notes
图片拷贝不过来,直接从github上下载 . 链接: https://github.com/DFX339/SpringBootDocumentNotes.git Create a example po ...
- PC/FORTH定点原理
body, table{font-family: 微软雅黑} table{border-collapse: collapse; border: solid gray; border-width: 2p ...
- 最短路径:Dijkstra & Floyd 算法图解,c++描述
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- (C/C++学习笔记) 二十一. 异常处理
二十一. 异常处理 ● 异常的概念 程序的错误通常包括:语法错误.逻辑错误.运行异常. 语法错误指书写的程序语句不合乎编译器的语法规则,这种错误在编译.连接时由编译器指出. 逻辑错误是指程序能顺利运行 ...
- jmeter4.0 源码编译 二次开发
准备: 1.jmeter4.0源码 - apache-jmeter-4.0_src.zip 2.IDE Eclipse - Oxygen.3 Release (4.7.3) 3.JDK - 1.8.0 ...
- 1.2socket服务器使用多线程
socket服务器代码如下 # -*- coding: utf-8 -*-from socket import * import time import threading,_thread as th ...
- table 奇行偶行
jquery 方法: $("tr:odd").//偶行 $("tr:even") //奇行
- 在MATLAB中安装MinGW-w64 C/C++ 编译器的方法
reference:http://blog.sina.com.cn/s/blog_167bbdec10102x113.html 在MATLAB中编译C/C++ 文件时出现以下情况: 说明缺少MinGW ...
- 强化学习10-Deep Q Learning-fix target
针对 Deep Q Learning 可能无法收敛的问题,这里提出了一种 fix target 的方法,就是冻结现实神经网络,延时更新参数. 这个方法的初衷是这样的: 1. 之前我们每个(批)记忆都 ...
- 杭电多校第七场 1010 Sequence(除法分块+矩阵快速幂)
Sequence Problem Description Let us define a sequence as below f1=A f2=B fn=C*fn-2+D*fn-1+[p/n] Your ...