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]然 ...
随机推荐
- Map集合遍历的四种方式理解和简单使用-----不能for循环遍历
Map集合遍历的四种方式理解和简单使用 ~Map集合是键值对形式存储值的,所以遍历Map集合无非就是获取键和值,根据实际需求,进行获取键和值 1:无非就是通过map.keySet()获取到值,然后 ...
- [Linux]Linux下修改snmp协议的默认161端口
一.Linux SNMP的配置 SNMP的简介和Linux下IPV4,IPV6地址的snmp协议开启可以参考上一个随笔:[Linux]CentOS6.9开启snmp支持IPV4和IPV6 二.修改默认 ...
- 《图解HTTP》读书笔记(转)
reference:https://www.cnblogs.com/edisonchou/p/6013450.html 目前国内讲解HTTP协议的书是在太少了,记忆中有两本被誉为经典的书<H ...
- 玩转X-CTR100 l STM32F4 l MPU6050加速度陀螺仪传感器
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] 本文介绍X-CTR100控制器 板载加速度 ...
- WebClient和WebRequest获取html代码
HTML: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.as ...
- Join Algorithm
Join(SQL) An SQL join clause combines columns from one or more tables in a relational database. It c ...
- wait_activity
wait_activity(self, activity, timeout, interval=1): android特有的 返回的True 或 False :Agrs: - activity - 需 ...
- pytest的fixture和conftest
解决问题:用例1需要先登录,用例2不需要登录,用例3需要先登录.很显然这就无法用setup和teardown来实现了,这个时候就可以自定义测试用例的预置条件,比setup灵活很多. 1.fixture ...
- input-event-codes.h
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Input event codes * * *** IMPORT ...
- ios中xib文件的用法
ZQRView文件: // // ZQRView.h // // // Created by zzqqrr on 17/8/20. // // #import <UIKit/UIKit.h> ...