POJ 3518 Boring

Problem : 给一个串S,询问串S有多个子串出现至少两次且位置不重叠。

Solution : 对S串建立后缀自动机,再建立后缀树,dfs一遍统计处每个结点的子树中最长节点max和最短节点min。枚举一遍后缀自动机的节点,那么对于其对应后缀的长度要求为小于等于max - min。

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. const int N = 1000008;
  5. const int INF = 2000000008;
  6. struct edge
  7. {
  8. int u, v, nt;
  9. };
  10. struct suffix_automanon
  11. {
  12. int nt[N][26], fail[N], a[N], qmin[N], qmax[N];
  13. int tot, last, root;
  14. int lt[N], sum;
  15. int p, q, np, nq;
  16. edge eg[N << 1];
  17. void add(int u, int v)
  18. {
  19. eg[++sum] = (edge){u, v, lt[u]}; lt[u] = sum;
  20. }
  21. int newnode(int len)
  22. {
  23. for (int i = 0; i < 26; ++i) nt[tot][i] = -1;
  24. fail[tot] = -1; a[tot] = len; qmax[tot] = 0; qmin[tot] = INF;
  25. lt[tot] = 0;
  26. return tot++;
  27. }
  28. void clear()
  29. {
  30. tot = 0;
  31. root = last = newnode(0);
  32. }
  33. void insert(int ch)
  34. {
  35. p = last; np = last = newnode(a[p] + 1); qmin[np] = qmax[np] = a[np];
  36. for (; ~p && nt[p][ch] == -1; p = fail[p]) nt[p][ch] = np;
  37. if (p == -1) fail[np] = root;
  38. else
  39. {
  40. q = nt[p][ch];
  41. if (a[p] + 1 == a[q]) fail[np] = q;
  42. else
  43. {
  44. nq = newnode(a[p] + 1);
  45. for (int i = 0; i < 26; ++i) nt[nq][i] = nt[q][i];
  46. fail[nq] = fail[q];
  47. fail[q] = fail[np] = nq;
  48. for (; ~p && nt[p][ch] == q; p = fail[p]) nt[p][ch] = nq;
  49. }
  50. }
  51. }
  52. void dfs(int u)
  53. {
  54. for (int i = lt[u]; i; i = eg[i].nt)
  55. {
  56. // cout << u << " " << eg[i].v << endl;
  57. int v = eg[i].v;
  58. dfs(v);
  59. qmax[u] = max(qmax[u], qmax[v]);
  60. qmin[u] = min(qmin[u], qmin[v]);
  61. }
  62. }
  63. void solve()
  64. {
  65. long long ans = 0;
  66. for (int i = 1; i < tot; ++i) add(fail[i], i);
  67. dfs(root);
  68. // for (int i = 1; i < tot; ++i) cout << qmin[i] << " " << qmax[i] << endl;
  69. for (int i = 1; i < tot; ++i)
  70. {
  71. int len = qmax[i] - qmin[i];
  72. if (len > a[fail[i]]) ans += min(a[i], len) - a[fail[i]];
  73. }
  74. cout << ans << endl;
  75. }
  76. }sam;
  77. int main()
  78. {
  79. string s;
  80. while (cin >> s)
  81. {
  82. if (s == "#") break;
  83. sam.clear();
  84. for (int i = 0, len = s.length(); i < len; ++i)
  85. sam.insert(s[i] - 'a');
  86. sam.solve();
  87. }
  88. }

POJ 3518 (后缀自动机)的更多相关文章

  1. POJ 3415 (后缀自动机)

    POJ 3415 Common Substrings Problem : 给两个串S.T (len <= 10^5), 询问两个串有多少个长度大于等于k的子串(位置不同也算). Solution ...

  2. Boring counting HDU - 3518 后缀自动机

    题意: 对于给出的字符串S, 长度不超过1000, 求其中本质不同的子串的数量, 这些子串满足在字符串S中出现了至少不重合的2次 题解: 将串放入后缀自动机中然后求出每一个节点对应的子串为后缀的子串出 ...

  3. POJ - 1743 后缀自动机

    POJ - 1743 顺着原字符串找到所有叶子节点,然后自下而上更新,每个节点right的最左和最右,然后求出答案. #include<cstdio> #include<cstrin ...

  4. POJ 1509 Glass Beads 后缀自动机 模板 字符串的最小表示

    http://poj.org/problem?id=1509 后缀自动机其实就是一个压缩储存空间时间(对节点重复利用)的储存所有一个字符串所有子串的trie树,如果想不起来长什么样子可以百度一下找个图 ...

  5. UVA 719 / POJ 1509 Glass Beads (最小表示法/后缀自动机)

    题目大意: 给出一个长度为N的字符串,求其字典序最小的循环同构. N<=10W. 算法讨论: 算法一.最小表示法.定义题. 算法二.后缀自动机. Codes: #include <iost ...

  6. POJ.2774.Long Long Message/SPOJ.1811.LCS(后缀自动机)

    题目链接 POJ2774 SPOJ1811 LCS - Longest Common Substring 确实比后缀数组快多了(废话→_→). \(Description\) 求两个字符串最长公共子串 ...

  7. poj 1743 Musical Theme 后缀自动机/后缀数组/后缀树

    题目大意 直接用了hzwer的题意 题意:有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的主题."主题&qu ...

  8. Common Substrings POJ - 3415 (后缀自动机)

    Common Substrings \[ Time Limit: 5000 ms\quad Memory Limit: 65536 kB \] 题意 给出两个字符串,要求两个字符串公共子串长度不小于 ...

  9. POJ - 2774 Long Long Message (后缀数组/后缀自动机模板题)

    后缀数组: #include<cstdio> #include<algorithm> #include<cstring> #include<vector> ...

随机推荐

  1. jsp声明周期

    https://www.w3cschool.cn/jsp/jsp-life-cycle.html 几点注意: jsp初始化期: 容器载入jsp文件后,它会在为请求提供任何服务前调用jspinit()方 ...

  2. android开发学习——android studio 引入第三方库的总结

    http://www.jianshu.com/p/0c592fff5d89 总结的很溜

  3. ssm基础配置

    1.导包 <dependencies> <dependency> <groupId>org.springframework</groupId> < ...

  4. Pycharm+Django+Python+MySQL开发 后台管理数据库

    Django框架十分简单易用,适合搭建个人博客网站.网上有很多教程,大多是关于命令行操作Django,这里分享一些用最新工具进行Django开发过程,主要是PyCharm太强大,不用有点可惜. 第一次 ...

  5. TinyMCE编辑器

    TinyMCE编辑器下载地址   http://www.tinymce.com/download/download.php

  6. Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置文件

    导航 目   录:Farseer.net轻量级ORM开源框架 目录 上一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:新版本说明 下一篇:Farseer.net轻量级ORM开源框架 ...

  7. JFreeChart应用(生成折线图)

    1.jar包,jcommon.jar和jfreechart.jar,具体用哪个版本官网去down吧: 还有另外一个jar包,gnujaxp.jar,这个引入之后编译的时候会报错,应该是xsd校验的问题 ...

  8. MATLAB 中的randn函数

    matlab函数 randn:产生正态分布的随机数或矩阵的函数 randn:产生均值为0,方差σ^2 = 1,标准差σ = 1的正态分布的随机数或矩阵的函数. 用法: Y = randn(n):返回一 ...

  9. OpenCV3.3安装教程

    http://blog.csdn.net/amusi1994/article/details/76768775?locationNum=10&fps=1

  10. spring mvc 配置运行报错误

    四月 06, 2015 10:51:18 上午 org.apache.catalina.startup.VersionLoggerListener log 信息: Server version: Ap ...