[SPOJ8222]NSUBSTR - Substrings(后缀自动机)
来源:互联网 发布:coc黑水罐升级数据 编辑:程序博客网 时间:2024/04/28 10:07
题目描述
传送门
题意:定义f(i)为长度为i的子串的最多出现次数(可重复),求f(1…n)
题解
很显然f(1..n)不升,那么可以用f(i)=max{f(i),f(i+1)}
right集合表示当前状态在哪里出现过,其实就是求right集合的大小
主链上的所有的点right集合初始为1(因为它代表了原串的一个前缀)
如果两个点的right集合有交集,那么一定一个是另一个的真子集
所以在parent树上把儿子的right集合都累加到父亲上就行了
而对于某一个点x,如果其right集合大小为y,那么f(step(x))至少为y
代码
#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define N 500005char s[N];int n,p,np,q,nq,root,sz,last;int ch[N][30],pre[N],step[N],c[N],pt[N],rt[N],f[N];void extend(){ for (int i=0;i<n;++i) { int x=s[i]-'a'; p=last;np=++sz;last=np; step[np]=step[p]+1; while (p&&!ch[p][x]) { ch[p][x]=np; p=pre[p]; } if (!p) pre[np]=root; else { q=ch[p][x]; if (step[q]==step[p]+1) pre[np]=q; else { nq=++sz; step[nq]=step[p]+1; memcpy(ch[nq],ch[q],sizeof(ch[q])); pre[nq]=pre[q]; pre[np]=pre[q]=nq; while (ch[p][x]==q) { ch[p][x]=nq; p=pre[p]; } } } }}int main(){ gets(s);n=strlen(s); last=root=++sz; extend(); for (int i=1;i<=sz;++i) ++c[step[i]]; for (int i=1;i<=n;++i) c[i]+=c[i-1]; for (int i=sz;i>=1;--i) pt[c[step[i]]--]=i; p=root; for (int i=0;i<n;++i) { int x=s[i]-'a'; p=ch[p][x]; ++rt[p]; } for (int i=sz;i>=1;--i) { p=pt[i]; rt[pre[p]]+=rt[p]; } for (int i=1;i<=sz;++i) f[step[i]]=max(f[step[i]],rt[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]);}
0 0
- [SPOJ8222]NSUBSTR - Substrings(后缀自动机)
- 【spoj8222】Substrings 后缀自动机
- spoj 8222 Substrings(NSUBSTR),后缀自动机
- SPOJ 8222 NSUBSTR - Substrings (后缀自动机)
- spoj8222:Substrings 后缀自动机+DP
- SPOJ NSUBSTR Substrings 后缀自动机
- SPOJ - NSUBSTR Substrings 后缀自动机
- [SPOJ8222]NSUBSTR - Substrings
- SPOJ NSUBSTR(后缀自动机)
- SPOJ 题目 8222 NSUBSTR - Substrings(后缀自动机+DP求子串出现最大次数)
- 后缀自动机(子串个数)spoj8222
- spoj8222:Substring(后缀自动机+拓扑排序)
- 【后缀自动机】 SPOJ NSUBSTR
- [SPOJ8222]NSUBSTR
- SPOJ NSUBSTR(Substrings-后缀自动机统计串出现次数-Right集合&Parent树の暴走)
- SPOJ 8222 NSUBSTR 后缀自动机
- 后缀自动机1002 SPOJ NSUBSTR
- SPOJ NSUBSTR 后缀自动机+DP
- 更换mysql数据目录后出现ERROR 2002 (HY000): Can't connect to local MySQL serve
- hdu1249(三角形划分区域,直线划分区域,折线划分区域)
- 关于memcached 总结
- linux环境消息队列
- new 和malloc relloc
- [SPOJ8222]NSUBSTR - Substrings(后缀自动机)
- 嵌入式软件入门必读,做好成为嵌入式软件大咖的准备
- 【数据结构与算法】二分查找
- 元素marign与padding的百分比设置
- docker 的自动构建
- DIV+CSS学习笔记总结篇
- Android开发传感器概述
- Android Https相关完全解析 当OkHttp遇到Https
- JavaScript常用的代码片段