题意

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

分析

我们建出后缀自动机,然后预处理出每个状态的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]).想想为什么?

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <iostream>
  5.  
  6. using namespace std;
  7. const int maxn=+;
  8. char s[maxn];
  9. int n;
  10. struct state{
  11. int len,link;
  12. int ch[];
  13. }st[maxn*];
  14. int sz,last,cur,cnt[*maxn],c[*maxn],f[maxn];
  15. void init(){
  16. cur=last=;
  17. sz=;
  18. st[].link=-;
  19. st[].len=;
  20. memset(st[].ch,-,sizeof(st[].ch));
  21. }
  22. void build_sam(int c){
  23. cur=sz++;
  24. st[cur].len=st[last].len+;
  25. cnt[cur]=;
  26. memset(st[cur].ch,-,sizeof(st[cur].ch));
  27. int p;
  28. for(p=last;p!=-&&st[p].ch[c]==-;p=st[p].link)
  29. st[p].ch[c]=cur;
  30. if(p==-)
  31. st[cur].link=;
  32. else{
  33. int q=st[p].ch[c];
  34. if(st[q].len==st[p].len+)
  35. st[cur].link=q;
  36. else{
  37. int clone=sz++;
  38. st[clone].len=st[p].len+;
  39. st[clone].link=st[q].link;
  40. for(int i=;i<;i++)
  41. st[clone].ch[i]=st[q].ch[i];
  42. for(;p!=-&&st[p].ch[c]==q;p=st[p].link)
  43. st[p].ch[c]=clone;
  44. st[q].link=st[cur].link=clone;
  45. }
  46. }
  47. last=cur;
  48. }
  49. int cmp(int a,int b){
  50. return st[a].len>st[b].len;
  51. }
  52. int main(){
  53. scanf("%s",s);
  54. n=strlen(s);
  55. init();
  56. for(int i=;i<n;i++)
  57. build_sam(s[i]-'a');
  58. for(int i=;i<sz;i++)
  59. c[i]=i;
  60. sort(c,c+sz,cmp);
  61. // for(int i=0;i<sz;i++){
  62. // printf("%d\n",st[i].link);
  63. // }
  64. // printf("!!\n");
  65.  
  66. for(int i=;i<sz;i++){
  67. int o=c[i];
  68. cnt[st[o].link]+=cnt[o];
  69. }
  70. // for(int i=0;i<sz;i++)
  71. // printf("%d ",cnt[i]);
  72. // printf("\n");
  73.  
  74. for(int i=;i<sz;i++)
  75. f[st[i].len]=max(f[st[i].len],cnt[i]);
  76. for(int i=n-;i>=;i--)
  77. f[i]=max(f[i],f[i+]);
  78. for(int i=;i<=n;i++){
  79. printf("%d\n",f[i]);
  80. }
  81. return ;
  82. }

【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. Tornado部署与运行

    运行多个Tornado实例 网页响应不是特别的计算密集型处理多个实例充分利用 CPU多端口怎么处理4.使用Supervisor监控Tornado进程安装(注意看是否需要指定使用python2版本) s ...

  2. dateframe行列插入和删除操作

    ar = np.array(list("ABCDEFG")) # array只是Convert,默认会copy源值.asarray也是Convert,如果源值是array则不cop ...

  3. 0基础自学php教程

    轻松搞定网页设计之html 一.HTML介绍 1. HTML概念 HTML(Hyper Text Markup Language),即超文本标记语言.是目前网络上应用最为广泛的语言,是构成网页文档的主 ...

  4. 数据结构与算法JavaScript描述——队列

    注:澄清一个bug: /** * 删除队首的元素: */ function dequeue(){ return this.dataStore.shift(); } 应该有return:   队列是一种 ...

  5. laravel 做图片的缩略图 踩坑

    系统需求 PHP >= 5.3 Fileinfo Extension GD Library (>=2.0) … or … Imagick PHP extension (>=6.5.7 ...

  6. JVM内存管理和问题简要分析学习

      Java中我们基本上不会显式地调用分配内存的函数,分配内存和回收内存都由JVM自动完成了.   所谓物理内存就是我们通常说的RAM(随机存储器),计算机中还有一个存储单元叫做寄存器,用于存储计算单 ...

  7. 第四章 istio快速入门(快速安装)

    4.1 环境介绍 K8s 1.9 以上版本. 4.2 快速部署Istio 下载:  https://github.com/istio/istio/releases/,  下载 1.1.0-snapsh ...

  8. 使用Ajax解析数据遇到的问题

    数据格式 我最近在使用JQuery的$.ajax访问后台的时候,发现竟然无法解析返回的数据,具体的错误记不清了(以后在遇到问题先截个图),可以在浏览器的Console中看到一个错误,但是去看这条请求是 ...

  9. C++ 栈 (链表实现)

    第一.基本概念 栈中的元素遵守“先进后出”的原则(LIFO,Last In First Out) 只能在栈顶进行插入和删除操作 压栈(或推入.进栈)即push,将数据放入栈顶并将栈顶指针加一 出栈(或 ...

  10. socket通信循环

    server-----------------#!/usr/bin/env python # encoding: utf-8  # Date: 2018/6/5 import socket phone ...