【题目链接】

  http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28005  

【题意】

给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值。求F(1)..F(Length(S))

【思路】

建立一个SAM。

  对于SAM的一个结点u所代表的串,它的长度为|min(u),max(u)|,出现次数为|right(s)|,出现次数可以通过fa边将max并到一块得到。

  max(fa)=min(u)-1

  这只考虑了结点的最长串,对于介于max(fa)与max(u)长度之间的串我们还需要按长度递推一遍,f[i]=max{ f[i+1],f[i] },这样保证长度i得到了至少应得到的值。

【代码】

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int N = *1e5+; char s[N];
int S,sz,last,ch[N][],fa[N],l[N]; void add(int x) {
int c=s[x]-'a';
int p=last,np=++sz; last=np;
l[np]=x;
for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
if(!p) fa[np]=S;
else {
int q=ch[p][c];
if(l[p]+==l[q]) fa[np]=q;
else {
int nq=++sz; l[nq]=l[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];
fa[np]=fa[q]=nq;
for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
}
}
} int b[N],r[N],f[N],t[N]; int main() {
scanf("%s",s+);
last=S=++sz;
int len=strlen(s+);
for(int i=;i<=len;i++) add(i);
for(int i=,p=S;i<=len;i++) {
p=ch[p][s[i]-'a']; r[p]++;
}
for(int i=;i<=sz;i++) b[l[i]]++;
for(int i=;i<=len;i++) b[i]+=b[i-];
for(int i=;i<=sz;i++) t[b[l[i]]--]=i; //基排
for(int i=sz;i;i--) r[fa[t[i]]]+=r[t[i]];
for(int i=;i<=sz;i++) f[l[i]]=max(f[l[i]],r[i]);
for(int i=len;i;i--) f[i]=max(f[i],f[i+]); //被包含的情况
for(int i=;i<=len;i++) printf("%d\n",f[i]);
return ;
}

spoj 8222 Substrings(后缀自动机+DP)的更多相关文章

  1. spoj 8222 Substrings (后缀自动机)

    spoj 8222 Substrings 题意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.求F(1)..F(Length(S)) 解题思路:我们构造S的SAM,那么对于 ...

  2. SPOJ NSUBSTR Substrings 后缀自动机

    人生第一道后缀自动机,总是值得纪念的嘛.. 后缀自动机学了很久很久,先是看CJL的论文,看懂了很多概念,关于right集,关于pre,关于自动机的术语,关于为什么它是线性的结点,线性的连边.许多铺垫的 ...

  3. SPOJ NSUBSTR Substrings ——后缀自动机

    建后缀自动机 然后统计次数,只需要算出right集合的大小即可, 然后更新f[l[i]]和rit[i]取个max 然后根据rit集合短的一定包含长的的性质,从后往前更新一遍即可 #include &l ...

  4. SPOJ8222 Substrings( 后缀自动机 + dp )

    题目大意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.F(1)..F(Length(S)) 建出SAM, 然后求出Right, 求Right可以按拓扑序dp..Right ...

  5. SP8222 NSUBSTR - Substrings(后缀自动机+dp)

    传送门 解题思路 首先建出\(sam\),然后把\(siz\)集合通过拓扑排序算出来.对于每个点只更新它的\(maxlen\),然后再从大到小\(dp\)一次就行了.因为\(f[maxlen-1]&g ...

  6. SPOJ 1812 LCS2 [后缀自动机 DP]

    题意: 求多个串<=10的最长连续子串 一个串建SAM,然后其他串在上面走 每个状态记录所有串在这个状态的公共子串的最小值 一个串在上面走的时候记录与每个状态公共子串的最大值,注意出现次数向父亲 ...

  7. SPOJ 8222. Substrings(后缀自动机模板)

    后缀自动机+dp. 后缀自动机主要是在functioner大牛那里学习的:http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html 这道题是在No_st ...

  8. spoj 1812 lcsII (后缀自动机)

    spoj 1812 lcsII (后缀自动机) 题意:求多个串的lcs,最多10个串,每个串最长10w 解题思路:后缀自动机.先建好第一个串的sam,然后后面的串拿上去跑(这个过程同前一题).sam上 ...

  9. 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp

    题目描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...

  10. ●SPOJ 8222 NSUBSTR–Substrings(后缀自动机)

    题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 后缀自动机的水好深啊!懂不了相关证明,带着结论把这个题做了.看来这滩深水要以后再来了. 本题要用到一个叫 R ...

随机推荐

  1. windows 7 64bit 下apache php mysql 环境配置

    在64位环境下安装apache,php和配置过程 准备好安装包.(64位版本) Apache 下载地址:http://www.apachelounge.com/download/ Php 下载地址:h ...

  2. python正则的中文处理

    因工作需要,要查找中文汉字分词,因为python正则表达式\W+表示的是所有的中文字就连标点符号都包括.所以要想办法过滤掉. 参考博客:http://log.medcl.net/item/2011/0 ...

  3. 更新 requests 包之后报 has no attribute '__getitem__' 的错

    翻代码的时候看到段一年多前用 python 写的下载图片站图片的代码. 测试下看还能不能下到图片,结果发现跑不起来了,报了个如下的错误: TypeError: 'instancemethod' obj ...

  4. WPF读书笔记 x名称空间详解(第二天)

    每天看一点,每天进步一点. x名称空间映射的是http://schemas.microsoft.com/winfx/2006/xaml,它包含的类均与解析XAML语言关,亦可称为"XAML名 ...

  5. c++ union学习

    看到公司前辈的代码中用到了union,不管是大学还是工作用到union机会比较少,还是挺新奇的.所以特意找些资料学习学习 前辈的代码: #include<iostream> using n ...

  6. Kinetic使用注意点--blob

    new Blob(config) 参数: config:包含所有配置项的对象. { points: "存放路径点的数组,可以用一层数组[a,b,c,d].二层数组[[a,b],[c,d]]或 ...

  7. 【Bean】 这才是bean,一直没仔细看

    EJB是Enterprise Java Bean的缩写,一个Bean扮演着应用程序素材的角色.它包含有一个functional interface,一个life-cycle interface,以及一 ...

  8. c语言通过89C51驱动1602液晶显示(入门级别)

    工具proteus,keil 步骤: 1.画好电路图 2.在指令模式下,设置好显示模式以及光标位置 3.在写数据模式下,向1602写入显示字符(1602只能显示数字和字符) 电路图 #include ...

  9. matlab怎么同时显示imshow 两幅图片

    matlab怎么同时显示imshow 两幅图片 matlab怎么同时显示imshow 两幅图片 方法一:subplot()函数 subplot(2,1,1); subplot(2,1,2); 分上下或 ...

  10. linux内存管理机制

    物理内存和虚拟内存 我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成,而内存是有限的,这样就引出了物理内存与虚拟内存的概念. 物理内存就是系统 ...