后缀自动机+dp。

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

这道题是在No_stop大牛那里学习的:http://blog.csdn.net/no__stop/article/details/11784715

特别感谢这两位大牛!贴上代码作为以后的模板吧。

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<cmath>
  6. #define LL long long
  7. #define CLR(a, b) memset(a, b, sizeof(a))
  8.  
  9. using namespace std;
  10. const int N = 550000;
  11.  
  12. struct suffix_automaton
  13. {
  14. char s[N];
  15. int chd[N][26],pre[N],step[N];
  16. int last,tot;
  17. inline void rush(int v)
  18. {
  19. step[++tot]=v;
  20. CLR(chd[tot], 0);
  21. }
  22. void Extend(int ch)
  23. {
  24. rush(step[last]+1);
  25. int p=last,np=tot;
  26. for (; !chd[p][ch]; p=pre[p]) chd[p][ch]=np;
  27. if (!p) pre[np]=1;
  28. else
  29. {
  30. int q=chd[p][ch];
  31. if (step[q]!=step[p]+1)
  32. {
  33. rush(step[p]+1);
  34. int nq=tot;
  35. memcpy(chd[nq],chd[q],sizeof(chd[q]));
  36. pre[nq]=pre[q];
  37. pre[q]=pre[np]=nq;
  38. for (; chd[p][ch]==q; p=pre[p]) chd[p][ch]=nq;
  39. } else pre[np]=q;
  40. }
  41. last=np;
  42. }
  43. void Build()
  44. {
  45. scanf("%s", s);
  46. tot = last = 1;
  47. CLR(pre,0);CLR(step,0);CLR(chd[1], 0);
  48. for (int i=0,End=strlen(s); i<End; i++) Extend(s[i]-'a');
  49. }
  50. int pos[N], cnt[N], dp[N], g[N];
  51. void Work()
  52. {
  53. Build();
  54. int len = strlen(s);dp[0] = 0;
  55. for(int i = 0; i <= len; i ++) cnt[i] = 0;///清零
  56. for(int i = 1; i <= tot; i ++) cnt[step[i]] ++;///统计长度为step[i]的节点个数。
  57. for(int i = 1; i <= len; i ++) cnt[i] += cnt[i - 1];///用来hash到(1-tot)。
  58. for(int i = 1; i <= tot; i ++) pos[cnt[step[i]] --] = i, g[i] = dp[i] = 0;///pos表示长度为step[i]的串位置为i。
  59. int p = 1;
  60. for(int i = 0; i < len; i ++) g[p = chd[p][s[i] - 'a']] ++;///顺着串走一遍
  61. for(int i = tot; i > 0; i --)///反着来,确保right集合可以用pre求个数。
  62. {
  63. p = pos[i];///反hash
  64. dp[step[p]] = max(dp[step[p]], g[p]);
  65. g[pre[p]] += g[p];///求right集合元素个数。
  66. }
  67. for(int i = len - 1; i > 0; i --)
  68. dp[i] = max(dp[i], dp[i + 1]);
  69. for(int i = 1; i <= len; i ++)
  70. printf("%d\n", dp[i]);
  71. }
  72. }Suf;
  73.  
  74. int main()
  75. {
  76. Suf.Work();
  77. }

SPOJ 8222. Substrings(后缀自动机模板)的更多相关文章

  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. spoj 1812 lcsII (后缀自动机)

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

  5. 牛客网 桂林电子科技大学第三届ACM程序设计竞赛 A.串串-后缀自动机模板题

    链接:https://ac.nowcoder.com/acm/contest/558/A来源:牛客网 A.串串 小猫在研究字符串. 小猫在研究字串. 给定一个长度为N的字符串S,问所有它的子串Sl…r ...

  6. hdu4622(后缀自动机模板)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意: 先输入一个长度为 n 的字符串, 然后有 q 个形如 l, r 的询问, 对于每个询问 ...

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

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

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

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

  9. spoj - Longest Common Substring(后缀自动机模板题)

    Longest Common Substring 题意 求两个串的最长公共子串. 分析 第一个串建后缀自动机,第二个串在自动机上跑,对于自动机上的结点(状态)而言,它所代表的最大长度为根结点到当前结点 ...

随机推荐

  1. 在VritualBox中安装CentOS7

    系统:Windows10 位 详细步骤参考: Windows平台上通过VirtualBox安装centos虚拟机 安装virtual box 出现2503错误解决:c:/windows/temp 添加 ...

  2. litecoin源码

    安装钱包 http://www.laiteb.com/92 莱特币基于比特币的v0.9.0rc2修改而来,从比较两者最新源码的分支图可以看出

  3. linux中find工具

    find 由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时间来了解一下.即使系统中含有网络文件系统( NFS),find命令在该文件系统中同样有效,只要你具有相应的权限. ...

  4. tornado 之 异步非阻塞

    异步非阻塞 1.基本使用 装饰器 + Future 从而实现Tornado的异步非阻塞 import tornado.web import tornado.ioloop from tornado im ...

  5. 【冷门】 C# 小技巧之获取变量名称

    今天在自我规范程序设计的时候,变量名匹配字符串来自配置文件,网上找了一会儿发现也有朋友在找寻这种方式,很不容易找到一个解决方案来自http://www.th7.cn/Program/net/20140 ...

  6. etcd raft library

    https://github.com/coreos/etcd/tree/master/raft import "github.com/coreos/etcd/raft" ----- ...

  7. Linux运维入门(二):网络基础知识梳理02

    一,交换机的基本原理 1.1 数据链路层的功能 (1)数据链路层负责网络中相邻节点之间可靠的数据通信,并进行有效的流量控制. (2)数据链路层的作用包括数据链路的建立,维护与拆除,帧包装,帧传输,帧同 ...

  8. Linux实战教学笔记15:磁盘原理

    第十五节 磁盘原理 标签(空格分隔): Linux实战教学笔记 1,知识扩展 非脚本方式的一条命令搞定批量创建用户并设置随机10位字母数字组合密码. 1.1 sed的高级用法 [root@chensi ...

  9. 【bzoj3239】Discrete Logging

    [吐槽] 这题和[bzoj]2480一毛一样. 就是输入顺序和输出变了一下. 传送门:http://www.cnblogs.com/chty/p/6043707.html

  10. Nginx源码完全注释(8)ngx_errno.c

    errno.h中的strerror(int errno)可以确定指定的errno的错误的提示信息.在 Nginx 中,将所有错误提示信息预先存储在一个数组里,而预先确定这个数组的大小,是在自动化脚本中 ...