●SPOJ 8222 NSUBSTR–Substrings(后缀自动机)
题链:
http://www.spoj.com/problems/NSUBSTR/
题解:
后缀自动机的水好深啊!
懂不了相关证明,带着结论把这个题做了。
看来这滩深水要以后再来了。
本题要用到一个叫 Right[P] 的数组,
表示 P对应的子串在原串中出现的所有位置的末尾位置下标的集合。
本题中,用这个数组存储集合大小就好了,即 P对应的子串在原串中出现了Right[p]次。
而Right[P]的值,等于从改点出发到结束状态的方案数。
但这个不好求,而是要用到另一个求法:用 Parent树:
(暂时由结论可知)Right集合不相交,只存在并列和包含关系。
所以把原来的 pre[]的指向反向后,形成一棵树,那么父节点的Right值=sigma(子节点节点的Right)
又因为这个Parent树无法遍历,且注意到儿子节点的step一定大于父亲节点的step,
所以对所有节点桶排序后,反向枚举,去更新父亲就好了。
计算出了Right[P]后,答案就可以统计了,详见代码。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 500100
#define filein(x) freopen(#x".in","r",stdin);
#define fileout(x) freopen(#x".out","w",stdout);
using namespace std;
struct SAM{
int size,last,q,p,nq,np,len;
int pre[MAXN],step[MAXN],Right[MAXN],ch[MAXN][26];
int Newnode(int a,int b){
step[size]=a; memcpy(ch[size],ch[b],sizeof(ch[b]));
return size++;
}
void Extend(int x){
p=last; last=np=Newnode(step[p]+1,0);
while(p&&!ch[p][x]) ch[p][x]=np,p=pre[p];
if(!p) pre[np]=1;
else{
q=ch[p][x];
if(step[q]!=step[p]+1){
nq=Newnode(step[p]+1,q);
pre[nq]=pre[q]; pre[q]=pre[np]=nq;
while(p&&ch[p][x]==q) ch[p][x]=nq,p=pre[p];
}
else pre[np]=q;
}
}
void Make_Right(char *S){
static int c[MAXN],T[MAXN]; p=1;
for(int i=0;i<len;i++) p=ch[p][S[i]-'a'],Right[p]++; memset(c,0,sizeof(c));
for(int i=1;i<size;i++) c[step[i]]++;
for(int i=1;i<=len;i++) c[i]+=c[i-1];
for(int i=1;i<size;i++) T[c[step[i]]--]=i; for(int i=size-1;i;i--) Right[pre[T[i]]]+=Right[T[i]];
}
void Build(char *S){
len=strlen(S); memset(ch[0],0,sizeof(ch[0]));
size=1; last=Newnode(0,0); pre[last]=0;
for(int i=0;i<len;i++) Extend(S[i]-'a');
Make_Right(S);
}
}suf;
int ANS[MAXN];
char S[MAXN];
int main()
{
scanf("%s",S);
int len=strlen(S);
suf.Build(S); for(int i=1;i<suf.size;i++) ANS[suf.step[i]]=max(ANS[suf.step[i]],suf.Right[i]);
for(int i=len-1;i;i--) ANS[i]=max(ANS[i],ANS[i+1]);
for(int i=1;i<=len;i++) printf("%d\n",ANS[i]);
return 0;
}
●SPOJ 8222 NSUBSTR–Substrings(后缀自动机)的更多相关文章
- ●SPOJ 8222 NSUBSTR - Substrings(后缀数组)
题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 同届红太阳 --WSY给出的后缀数组解法!!! 首先用倍增算法求出 sa[i],rak[i],hei[i]然 ...
- SPOJ NSUBSTR Substrings 后缀自动机
人生第一道后缀自动机,总是值得纪念的嘛.. 后缀自动机学了很久很久,先是看CJL的论文,看懂了很多概念,关于right集,关于pre,关于自动机的术语,关于为什么它是线性的结点,线性的连边.许多铺垫的 ...
- SPOJ NSUBSTR Substrings ——后缀自动机
建后缀自动机 然后统计次数,只需要算出right集合的大小即可, 然后更新f[l[i]]和rit[i]取个max 然后根据rit集合短的一定包含长的的性质,从后往前更新一遍即可 #include &l ...
- ●SPOJ 8222 NSUBSTR–Substrings
题链: http://www.spoj.com/problems/NSUBSTR/题解: 后缀自动机. 不难发现,对于自动机里面的一个状态s, 如果其允许的最大长度为maxs[s],其right集合的 ...
- SPOJ 8222 NSUBSTR - Substrings
http://www.spoj.com/problems/NSUBSTR/ 题意: F(x)定义为字符串S中所有长度为x的子串重复出现的最大次数 输出F[1]~F[len(S)] 用字符串S构建后缀自 ...
- SPOJ8222 NSUBSTR - Substrings(后缀自动机)
You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as ...
- 【刷题】SPOJ 8222 NSUBSTR - Substrings
You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as ...
- SPOJ8222 NSUBSTR - Substrings 后缀自动机_动态规划
讲起来不是特别好讲.总之,如果 $dp[i+1]>=dp[i]$,故$dp[i]=max(dp[i],dp[i+1])$ Code: #include <cstdio> #inclu ...
- SP8222 NSUBSTR - Substrings(后缀自动机+dp)
传送门 解题思路 首先建出\(sam\),然后把\(siz\)集合通过拓扑排序算出来.对于每个点只更新它的\(maxlen\),然后再从大到小\(dp\)一次就行了.因为\(f[maxlen-1]&g ...
随机推荐
- 静态关键字static用法。
static的特点:1,static是一个修饰符,用于修饰成员.2,static修饰的成员被所有的对象所共享.3,static优先于对象存在,因为static的成员随着类的加载就已经存在了. 4,st ...
- 函数式编程之foldLeftViaFoldRight
问题来自 Scala 函数式编程 一书的习题, 让我很困扰, 感觉函数式编程有点神学的感觉.后面看懂之后, 又觉得函数式编程所提供的高阶抽象是多么的强大. 这个问题让我发呆了好久, 现在把自己形成的想 ...
- django启动uwsgi报错
查看uwsgi.log *** Starting uWSGI 2.0.17 (64bit) on [Thu Apr 5 17:46:15 2018] *** compiled with version ...
- 腾讯云服务器上安装phstudy和lnmp
phpstudy的安装:wget -c http://lamp.phpstudy.net/phpstudy.bin chmod +x phpstudy.bin #权限设置./phpstudy.bin ...
- LeetCode & Q27-Remove Element-Easy
Array Two Pointers Description: Given an array and a value, remove all instances of that value in pl ...
- node express将请求重定向为https
项目开发时,由于服务器只接受https请求(运维说了算...),所以在生产环境时,要把所有http请求全都重定向为https,具体操作是在app.js文件里加入以下代码: var express = ...
- Python内置函数(8)——bool
英文文档: class bool([x]) Return a Boolean value, i.e. one of True or False. x is converted using the st ...
- restful架构风格设计准则(四)资源表示和资源访问
读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! 一.资源表示 1.资源表示:使用 单数 vs. 复数 如果一个URL所对 ...
- [机器学习Lesson3] 梯度下降算法
1. Gradient Descent(梯度下降) 梯度下降算法是很常用的算法,可以将代价函数J最小化.它不仅被用在线性回归上,也被广泛应用于机器学习领域中的众多领域. 1.1 线性回归问题应用 我们 ...
- WPF项目学习.四
信息收录项目 版权声明:本文为博主初学经验,未经博主允许不得转载. 一.前言 记录在学习与制作WPF过程中遇到的解决方案. 需求文案.设计思路.简要数据库结构.简要流程图和明细代码,动图细化每步操作 ...