题意

给出一个字符串,要你找出所有长度的子串分别的最多出现次数。

分析

我们建出后缀自动机,然后预处理出每个状态的cnt,cnt[u]指的是u这个状态的right集合大小。我们设f[len]为长度为len的子串的最多出现次数。我们对于自动机的每个状态都更新f,f[st[u].len]=max(f[st[u].len],cnt[u])。然后这样更新完以后,可以神奇的dp一下。f[len]=max(f[len],f[len+1]).想想为什么?

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream> using namespace std;
const int maxn=+;
char s[maxn];
int n;
struct state{
int len,link;
int ch[];
}st[maxn*];
int sz,last,cur,cnt[*maxn],c[*maxn],f[maxn];
void init(){
cur=last=;
sz=;
st[].link=-;
st[].len=;
memset(st[].ch,-,sizeof(st[].ch));
}
void build_sam(int c){
cur=sz++;
st[cur].len=st[last].len+;
cnt[cur]=;
memset(st[cur].ch,-,sizeof(st[cur].ch));
int p;
for(p=last;p!=-&&st[p].ch[c]==-;p=st[p].link)
st[p].ch[c]=cur;
if(p==-)
st[cur].link=;
else{
int q=st[p].ch[c];
if(st[q].len==st[p].len+)
st[cur].link=q;
else{
int clone=sz++;
st[clone].len=st[p].len+;
st[clone].link=st[q].link;
for(int i=;i<;i++)
st[clone].ch[i]=st[q].ch[i];
for(;p!=-&&st[p].ch[c]==q;p=st[p].link)
st[p].ch[c]=clone;
st[q].link=st[cur].link=clone;
}
}
last=cur;
}
int cmp(int a,int b){
return st[a].len>st[b].len;
}
int main(){
scanf("%s",s);
n=strlen(s);
init();
for(int i=;i<n;i++)
build_sam(s[i]-'a');
for(int i=;i<sz;i++)
c[i]=i;
sort(c,c+sz,cmp);
// for(int i=0;i<sz;i++){
// printf("%d\n",st[i].link);
// }
// printf("!!\n"); for(int i=;i<sz;i++){
int o=c[i];
cnt[st[o].link]+=cnt[o];
}
// for(int i=0;i<sz;i++)
// printf("%d ",cnt[i]);
// printf("\n"); for(int i=;i<sz;i++)
f[st[i].len]=max(f[st[i].len],cnt[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 ;
}

【SPOJ -NSUBSTR】Substrings 【后缀自动机+dp】的更多相关文章

  1. SPOJ NSUBSTR Substrings 后缀自动机

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

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

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

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

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

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

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

  5. Substrings SPOJ - NSUBSTR (后缀自动机)

    Substrings \[ Time Limit: 100ms\quad Memory Limit: 1572864 kB \] 题意 给出一个长度为 \(250000\) 的字符串,求出所有 \(x ...

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

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

  7. SPOJ8222 NSUBSTR - Substrings(后缀自动机)

    You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as ...

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

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

  9. SPOJ8222 NSUBSTR - Substrings 后缀自动机_动态规划

    讲起来不是特别好讲.总之,如果 $dp[i+1]>=dp[i]$,故$dp[i]=max(dp[i],dp[i+1])$ Code: #include <cstdio> #inclu ...

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

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

随机推荐

  1. Oracle修改字段值包含&字符

    昨天在更新一个表的字段时发现pl/sql弹出变量框,它认为我要改的字段值中包含未定义的变量.比如我执行一个脚本: update t_wlf_config set configvalue = 'hell ...

  2. caffemodel的读取与修改

    直接撸代码~ import caffe import numpy as np caffe.set_mode_cpu() net = caffe.Net('myprototxt.prototxt', ' ...

  3. Unit04: JavaScript 概述 、 JavaScript 基础语法 、 流程控制

    Unit04: JavaScript 概述 . JavaScript 基础语法 . 流程控制 my.js function f3() { alert("唐胜伟"); } demo1 ...

  4. js 日期正则 转载

    天秤水的Blog 博客园 博问 闪存 首页 新随笔 联系 管理 订阅 随笔- 70  文章- 0  评论- 74    最强日期正则表达式   一.简单的日期判断(YYYY/MM/DD):  ^\d{ ...

  5. 如何利用JConsole观察分析Java程序的运行并进行排错调优_java

    如何利用JConsole观察分析Java程序的运行并进行排错调优_java 官方指导  use jconsole use jmx technology

  6. 模拟admin组件自己开发stark组件之创建篇

    admin组件 admin组件为我们提供了针对django管理页面 我们先简短来看下django的admin组件的启动流程,注册流程,url匹配过程 启动注册 1. 扫描所有应用下的注册了应用中的ad ...

  7. mongoDB在windows下安装和配置.

    1.首先在官网下载mongoDB的安装包: http://www.mongodb.org/downloads 这里我们下载zip格式的下载,其他的没安装过,不会,就不说了. 2.解压文件后: 3.在D ...

  8. Python ord(char)

    Given a string of length one, return an integer representing the Unicode code point of the character ...

  9. 第九章 消息总线: Spring Cloud Bus

    在微服务架构的系统中, 我们通常会使用轻量级的消息代理来构建一个共用的消息主题让系统中所有微服务实例都连接上来, 由于该主题中产生的消息会被所有实例监听和消费, 所以我们称它为消息总线. 在总线上的各 ...

  10. 说说JDK中的List-ArrayList、Vector、LinkedList

    为方便开发人员,JDK提供了一套主要数据结构的实现,比如List.Map等.今儿说说List接口. List接口的一些列实现中,最常用最重要的就是这三个:ArrayList.Vector.Linked ...