#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define maxn 500005
#define maxm 250005
using namespace std; int n,tot,root,last,f[maxm],fa[maxn],son[maxn][],dist[maxn],ri[maxn],sum[maxm],tmp[maxn];
char st[maxm];
struct Tsegment{
void prepare(){tot=root=last=; memset(dist,,sizeof(dist)); memset(sum,,sizeof(sum));}
int newnode(int x){
dist[++tot]=x; return tot;
}
void add(int x){
int p=last,np=newnode(dist[last]+); last=np;
for (;p&&!son[p][x];p=fa[p]) son[p][x]=np;
if (p==) fa[np]=root;
else{
int q=son[p][x];
if (dist[p]+==dist[q]) fa[np]=q;
else{
int nq=newnode(dist[p]+);
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q],fa[q]=fa[np]=nq;
for (;p&&son[p][x]==q;p=fa[p]) son[p][x]=nq;
}
}
}
}SAM; int main(){
scanf("%s",st+),n=strlen(st+);
SAM.prepare();
for (int i=;i<=n;i++) SAM.add(st[i]-'a');
last=root;
for (int i=;i<=n;i++) last=son[last][st[i]-'a'],ri[last]=;
memset(sum,,sizeof(sum));
for (int i=;i<=tot;i++) sum[dist[i]]++;
for (int i=;i<=n;i++) sum[i]+=sum[i-];
for (int i=;i<=tot;i++) tmp[sum[dist[i]]--]=i;
memset(f,,sizeof(f));
for (int i=tot;i>=;i--){
int x=tmp[i];
if (fa[x]) ri[fa[x]]+=ri[x];
}
for (int i=;i<=tot;i++) f[dist[i]]=max(f[dist[i]],ri[i]);
for (int i=n-;i>=;i--) f[i]=max(f[i],f[i+]);
for (int i=;i<=n;i++) printf("%d\n",f[i]);
return ;
}

题目链接:http://www.spoj.com/problems/NSUBSTR/

题目大意:给定一个长度为n的字符串,n<=250000,求f[i],i属于[1,n],f[i]表示在给定字符串中长度为i的子串的最多出现次数。

做法:初看此题,我也是一脸懵逼,后来发现出现次数与后缀自动机中的right集合大小有关,这题主要就是如何求right集合的大小,即该点表示的状态的右端点的个数(即出现次数),初始时我们从root开始匹配全串,途径的节点我们设其right为1,其余的节点设为0,某个节点的right就是parent树中以它为根的子树中的right值的和,一次dp即可。注解:parent树是我们记录的fa数组所构成的树,该步骤具体细节见代码。

dist表示SAM上该节点所表示的状态所能代表的最长的字符串长度,我们用right【i】去更新f【dist【i】】即可,最后用一次类似前缀和的算法,求一次后缀最值,显然,长度越小,出现次数一定不会减少。最后输出f数组即可。

后缀自动机。

【spoj8222】Substrings的更多相关文章

  1. 【spoj8222】 Substrings

    http://www.spoj.com/problems/NSUBSTR/ (题目链接) 题意 给出一个字符串S,令${F(x)}$表示S的所有长度为x的子串出现次数的最大值.求${F(1)..... ...

  2. 【SPOJ8222】Substrings (后缀自动机)

    题意: 给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值. 求F(1)..F(Length(S)) Length(S) <= 250000 思路:板子中st[x]定义为r ...

  3. 【SPOJ】Substrings(后缀自动机)

    [SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(rig ...

  4. 【SPOJ】Substrings

    出现次数很好处理,就是 \(right/endpos\) 集合的大小 那么,直接构建 \(SAM\) 求出每个位置的\(right\)集合大小 直接更新每个节点的\(longest\)就行了 最后短的 ...

  5. 【POJ1226】Substrings(后缀数组,二分)

    题意: n<=10,len<=100 思路: 只有一个字符串的时候特判一下 #include<cstdio> #include<cstring> #include& ...

  6. 【UVA10829】 L-Gap Substrings (后缀数组)

    Description If a string is in the form UVU, where U is not empty, and V has exactly L characters, we ...

  7. 【POJ3415】 Common Substrings(后缀数组|SAM)

    Common Substrings Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤ ...

  8. 【SPOJ】Distinct Substrings(后缀自动机)

    [SPOJ]Distinct Substrings(后缀自动机) 题面 Vjudge 题意:求一个串的不同子串的数量 题解 对于这个串构建后缀自动机之后 我们知道每个串出现的次数就是\(right/e ...

  9. 【SPOJ】Distinct Substrings/New Distinct Substrings(后缀数组)

    [SPOJ]Distinct Substrings/New Distinct Substrings(后缀数组) 题面 Vjudge1 Vjudge2 题解 要求的是串的不同的子串个数 两道一模一样的题 ...

随机推荐

  1. jquery 时间运算、格式化的方法扩张

    /* 函数:日期 加n天 参数:n是天数 返回:n天后的日期 */ Date.prototype.addDays = Date.prototype.addDays || function (n) { ...

  2. swift 集合类型(二)

    说到swift的集合类型,就不得不谈到Dictionary.包含一个键值对组合的集合. var air = ["name":"warner","tit ...

  3. Cordova - 与iOS原生代码交互2(使用Swift开发Cordova的自定义插件)

    在前一篇文章中我介绍了如何通过 js 与原生代码进行交互(Cordova - 与iOS原生代码交互1(通过JS调用Swift方法)),当时是直接对Cordova生成的iOS工程项目进行编辑操作的(添加 ...

  4. 2016年优秀的java网站分享

    java中文网站 伯乐在线java版:http://www.importnew.com/ 码农网:http://www.codeceo.com/ infoq:http://www.infoq.com/ ...

  5. Android系统启动分析(Init->Zygote->SystemServer->Home activity)

    整个Android系统的启动分为Linux Kernel的启动和Android系统的启动.Linux Kernel启动起来后,然后运行第一个用户程序,在Android中就是init程序. ------ ...

  6. HTML5之CSS3 3D transform 剖析式学习之一

    最近坐地铁发现“亚洲动物基金”在地铁上做了很多公益广告,比较吸引人的是一个月熊的广告.做的很可爱.回去就搜了一下,发现这个网站是HTML5做的,非常炫. 所以想学习一下,方法就是传统的学习办法,模仿. ...

  7. SQLite剖析之内核研究

    先从全局的角度把握SQLite内核各个模块的设计和功能.SQLite采用了层次化.模块化的设计,而这些使得它的可扩展性和可移植性非常强.而且SQLite的架构与通用DBMS的结构差别不是很大,所以它对 ...

  8. 柯尔莫可洛夫-斯米洛夫检验(Kolmogorov–Smirnov test,K-S test)

    柯尔莫哥洛夫-斯米尔诺夫检验(Колмогоров-Смирнов检验)基于累计分布函数,用以检验两个经验分布是否不同或一个经验分布与另一个理想分布是否不同. 在进行cumulative probab ...

  9. Bete冲刺第二阶段

    Bete冲刺第二阶段 今日工作: web: 修复了a版本中接口数据返回错误的问题.通知对数据表新增了几个字段.并且新增了一个通知查询的接口. ios: 修正网络连接bug 招募功能界面完成但是跳转问题 ...

  10. springMvc全局异常处理

    本文中只测试了:实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器 对已有代码没有入侵性等优点,同时,在异常处理时能获取导致出现异常的对象,有利于提 ...