题目链接

题意

对于给定的字符串,求有多少个 不重叠的子串 出现次数 \(\geq 2\).

思路

枚举子串长度 \(len\),以此作为分界值来对 \(height\) 值进行划分。

显然,对于每一组,组内子串具有一个长度为 \(len\) 的公共前缀。

至于是否重叠,只需判断 \(sa_{max}-sa_{min}\geq len\).

对于组间,显然它们的公共前缀互不相同,所以答案即为\(\sum_{len}\sum_{group}\)

Code

#include <bits/stdc++.h>
#define maxn 1010
using namespace std;
typedef long long LL;
int wa[maxn], wb[maxn], wv[maxn], wt[maxn], h[maxn], rk[maxn], sa[maxn], n, r[maxn];
char s[maxn];
char s1[maxn], s2[maxn];
bool cmp(int* r, int a, int b, int l) { return r[a] == r[b] && r[a+l] == r[b+l]; }
void init(int* r, int* sa, int n, int m) {
int* x=wa, *y=wb, *t, i, j, p;
for (i = 0; i < m; ++i) wt[i] = 0;
for (i = 0; i < n; ++i) ++wt[x[i] = r[i]];
for (i = 1; i < m; ++i) wt[i] += wt[i - 1];
for (i = n-1; i >= 0; --i) sa[--wt[x[i]]] = i;
for (j = 1, p = 1; p < n; j <<= 1, m = p) {
for (p = 0, i = n-j; i < n; ++i) y[p++] = i;
for (i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
for (i = 0; i < n; ++i) wv[i] = x[y[i]];
for (i = 0; i < m; ++i) wt[i] = 0;
for (i = 0; i < n; ++i) ++wt[wv[i]];
for (i = 1; i < m; ++i) wt[i] += wt[i - 1];
for (i = n-1; i >= 0; --i) sa[--wt[wv[i]]] = y[i];
t = x, x = y, y = t, x[sa[0]] = 0;
for (p = 1, i = 1; i < n; ++i) x[sa[i]] = cmp(y, sa[i], sa[i-1], j) ? p - 1 : p++;
} for (i = 0; i < n; ++i) rk[sa[i]] = i;
int k = 0;
for (i = 0; i < n - 1; h[rk[i++]] = k) {
for (k = k ? --k : 0, j = sa[rk[i] - 1]; r[i+k] == r[j+k]; ++k);
}
}
void work() {
int tot=0, m=0;
for (int i = 0; s[i]; ++i) m = max(r[tot++] = s[i], m);
r[tot++] = 0;
init(r, sa, tot, ++m);
int ans = 0;
for (int len = 1; len < (tot+1)/2; ++len) {
int minn = maxn, maxx = 0;
for (int i = 1; i < tot; ++i) {
if (h[i] < len) {
ans += maxx-minn >= len ? 1 : 0;
minn = sa[i], maxx = sa[i];
}
else minn = min(minn, sa[i]), maxx = max(maxx, sa[i]);
}
ans += maxx-minn >= len ? 1 : 0;
}
printf("%d\n", ans);
}
int main() {
while (scanf("%s", s) != EOF && s[0] != '#') work();
return 0;
}

hdu 3518 Boring counting 后缀数组 height分组的更多相关文章

  1. hdu 3518 Boring counting 后缀数组LCP

    题目链接 题意:给定长度为n(n <= 1000)的只含小写字母的字符串,问字符串子串不重叠出现最少两次的不同子串个数; input: aaaa ababcabb aaaaaa # output ...

  2. hdu 3518 Boring counting 后缀数组

    题目链接 根据height数组的性质分组计算. #include <iostream> #include <vector> #include <cstdio> #i ...

  3. hdu 3518 Boring counting 后缀数组基础题

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...

  4. 后缀数组 --- HDU 3518 Boring counting

    Boring counting Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3518 Mean: 给你一个字符串,求:至少出 ...

  5. HDU 3518 Boring counting(后缀数组,字符处理)

    题目 参考自:http://blog.sina.com.cn/s/blog_64675f540100k9el.html 题目描述: 找出一个字符串中至少重复出现两次的字串的个数(重复出现时不能重叠). ...

  6. HDU 3518 Boring counting

    题目:Boring counting 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3518 题意:给一个字符串,问有多少子串出现过两次以上,重叠不能算两次 ...

  7. hdu3518 Boring counting(后缀数组)

    Boring counting 题目传送门 解题思路 后缀数组.枚举每种长度,对于每个字符串,记录其最大起始位置和最小起始位置,比较是否重合. 代码如下 #include <bits/stdc+ ...

  8. [八分之一的男人]POJ - 1743 后缀数组 height分组 带详解

    题意:求最长不可重叠的相同差值子串的长度 这道题算是拖了好几个月,现在花了点时间应该搞懂了不少,尝试分析一下 我们首先来解决一个退化的版本,求最长不可重叠的相同子串(差值为0) 比如\(aabaaba ...

  9. acdream 1430 SETI 后缀数组+height分组

    这题昨天比赛的时候逗了,后缀想不出来,由于n^2的T了,就没往后缀数组想--并且之后解题的人又说用二分套二分来做.然后就更不会了-- 刚才看了题解,唉--原来题讲解n^2的也能够过,然后就--这样了! ...

随机推荐

  1. Session 会话保持

    本文将详细讨论session的工作机制并且对在Java web application中应用session机制时常见的问题作出解答 一.术语session session,中文经常翻译为会话,其本来的 ...

  2. 快速搭建FTP服务

    Linux下ftp服务可以通过搭建vsftpd服务来实现,以CentOS为例,首先查看系统中是否安装了vsftpd,可以通过执行命令 rpm -qa | grep vsftpd 来查看是否安装相应的包 ...

  3. atm-interface-shopping

    from db import db_handlerfrom interface import bank def shopping_interface(name, cost, shoppingcart) ...

  4. php同一个用户同时只能登陆一个, 后登陆者踢掉前登陆者(排他登陆)

    通常用户登陆,如果没有特别的限定, 同一个用户可以同时登陆, 今天搞了一个东西限定一个用户不能同时登陆到一个系统上, 后登陆者会把前面登陆的踢出来.(有点像QQ,同个帐号不能在多个地方同时在线, 后面 ...

  5. 绘制圆形 和 椭圆形:边圆形 imageellipse() 、 填充圆形imagefilledellipse()

    <?php //1. 绘制图像资源(创建一个画布) $image = imagecreatetruecolor(500, 300); //2. 先分配一个绿色 $green = imagecol ...

  6. HDU 1423 Greatest Common Increasing Subsequence(LCIS)

    Greatest Common Increasing Subsequenc Problem Description This is a problem from ZOJ 2432.To make it ...

  7. hihocoder1015 kmp算法

    #1015 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在 ...

  8. 8 REST Framework 实现Web API 1

    1 参考博客: http://blog.csdn.net/SVALBARDKSY/article/details/50548073 2  准备工作 1. 环境 Python: Python 3.5 D ...

  9. synchronized同步方法和同步代码块的区别

    同步方法默认使用this或者当前类做为锁. 同步代码块可以选择以什么来加锁,比同步方法更精确,我们可以选择只有会在同步发生同步问题的代码加锁,而并不是整个方法. 同步方法使用synchronized修 ...

  10. javascript 实现九九乘法表

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...