后缀数组2倍增可解。

 #include <cstdio>
#include <cstring>
#include <cstdlib> #define MAXN 1005
#define INF 0xfffff
#define MAXM 27 int wa[MAXN], wb[MAXN], ws[MAXN], wv[MAXN];
char s[MAXN];
int str[MAXN], sa[MAXN];
int height[MAXN], rank[MAXN]; int max(int a, int b) {
return a>b ? a:b;
} int min(int a, int b) {
return a<b ? a:b;
} int cmp(int *r, int a, int b, int l) {
return r[a]==r[b] && r[a+l]==r[b+l];
} void da(int *r, int *sa, int n, int m) {
int i, j, *x = wa, *y = wb, *t;
int p; for (i=; i<m; ++i) ws[i] = ;
for (i=; i<n; ++i) ws[x[i]=r[i]]++;
for (i=; i<m; ++i) ws[i] += ws[i-];
for (i=n-; i>=; --i) sa[--ws[x[i]]] = i;
for (j=, p=; j<n; j*=, m=p) {
for (p=, i=n-j; i<n; ++i) y[p++] = i;
for (i=; i<n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
for (i=; i<n; ++i) wv[i] = x[y[i]];
for (i=; i<m; ++i) ws[i] = ;
for (i=; i<n; ++i) ws[wv[i]]++;
for (i=; i<m; ++i) ws[i] += ws[i-];
for (i=n-; i>=; --i) sa[--ws[wv[i]]] = y[i];
for (t=x, x=y, y=t, p=, x[sa[]]=, i=; i<n; ++i)
x[sa[i]] = cmp(y, sa[i-], sa[i], j) ? p- : p++;
}
} void calheight(int *r, int *sa, int n) {
int i, j, k = ; for (i=; i<=n; ++i) rank[sa[i]] = i;
for (i=; i<n; height[rank[i++]]=k)
for (k? --k:, j=sa[rank[i]-]; r[i+k]==r[j+k]; ++k)
/*do nothing*/;
} int getRepeat(int len, int n) {
int i, maxx, minn;
int ret = ; maxx = -;
minn = INF; for (i=; i<=n; ++i) {
if (height[i] >= len) {
maxx = max(sa[i], max(sa[i-], maxx));
minn = min(sa[i], min(sa[i-], minn));
} else {
if (maxx!=- && minn!=INF && (maxx-minn)>=len)
++ret;
maxx = -;
minn = INF;
}
} if (maxx!=- && minn!=INF && (maxx-minn)>=len)
++ret; return ret;
} void printRank(int n) {
int i; printf("print rank...\n");
for (i=; i<=n; ++i)
printf("%d ", rank[i]);
printf("\n");
} void printHeight(int n) {
int i; printf("print height...\n");
for (i=; i<=n; ++i)
printf("%d ", height[i]);
printf("\n");
} void printSa(int n) {
int i; printf("print sa...\n");
for (i=; i<=n; ++i)
printf("%d ", sa[i]);
printf("\n");
} int main() {
int i, len;
int ans; #ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif while (scanf("%s",s)!=EOF && (s[]!='#')) {
//printf("%s\n", s);
for (i=; s[i]; ++i)
str[i] = s[i] - 'a' + ;
str[i] = ;
len = i;
da(str, sa, len+, MAXM);
calheight(str, sa, len);
#ifndef ONLINE_JUDGE
printSa(len);
printRank(len);
printHeight(len);
#endif
for (ans=, i=; i<=len/; ++i) {
ans += getRepeat(i, len);
}
printf("%d\n", ans);
} return ;
}

【HDOJ】3518 Boring Counting的更多相关文章

  1. 【HDOJ】4358 Boring counting

    基本思路是将树形结构转线性结构,因为查询的是从任意结点到叶子结点的路径.从而将每个查询转换成区间,表示从该结点到叶子结点的路径.离线做,按照右边界升序排序.利用树状数组区间修改.树状数组表示有K个数据 ...

  2. HDOJ 题目3518 Boring counting(后缀数组,求不重叠反复次数最少为2的子串种类数)

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

  3. 【HDOJ】P5056 Boring count

    题目意思是给你一个字符串和K,让你求其中有多少个字串中每个字母的出现次数不超过K次,可以等于 题目意思是很简单的,写起来也很简单,不过就是注意最后要是long long要不WA了,555~ #incl ...

  4. HDOJ 3518 Boring counting

    SAM基本操作 拓扑寻求每个节点  最左边的出现left,最右边的出现right,已经有几个num ...... 对于每个出现两次以上的节点.对其所相应的一串子串的长度范围 [fa->len+1 ...

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

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

  6. HDU 3518 Boring counting

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

  7. 【HDOJ】4729 An Easy Problem for Elfness

    其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...

  8. 【HDOJ】【3506】Monkey Party

    DP/四边形不等式 裸题环形石子合并…… 拆环为链即可 //HDOJ 3506 #include<cmath> #include<vector> #include<cst ...

  9. 【HDOJ】【3516】Tree Construction

    DP/四边形不等式 这题跟石子合并有点像…… dp[i][j]为将第 i 个点开始的 j 个点合并的最小代价. 易知有 dp[i][j]=min{dp[i][j] , dp[i][k-i+1]+dp[ ...

随机推荐

  1. UVA1588(Kickdown)。

    只需要固定长串,拿着短串移动就好了. 我是从右往左移动,需要注意的是要判断两头重叠部分(左端重叠和右端重叠)的大小关系. #include <iostream> #include < ...

  2. python Eve RESTFul 尝试笔记

    0.前言 最近重点研究了yeelink平台的原理和使用,yeelink平台和多数云平台设计一样应用了RESTFul框架.嵌入式侧(或者是客服端侧)的相关技术研究的比较充分(个人这么认为),是不是该弄弄 ...

  3. JavaScript新手学习笔记1——数组

    今天,我复习了一下JavaScript的数组相关的知识,总结一下数组的API: 总共有11个API:按照学习的先后顺序来吧,分别是: ① toString()  语法:arr.toString(); ...

  4. Java基础知识强化之IO流笔记03:throws的方式处理异常

    1. 什么时候使用throws ? (1)定义功能方法时候,需要把出现的问题暴露出来,让调用者去处理.那么就通过throws在方法上标识. (2)有时候,我们是可以对异常进行处理的,但是又有些时候,我 ...

  5. linux系统应用--Linux下用virtualBox安装win7(共享文件夹)

    1. deepin终端: sudo apt-get install virtualbox 2. 下载win7 iso文件 3. deepin终端启动virtualbox   : ./virtualbo ...

  6. ASP.NET-FineUI开发实践-9(三)

    1. TextChanged事件前台触发回发后台,接上文,先给TextBox1加上事件,看看是怎么生成出来的, 注意AutoPostBack="true",找源代码,f4多出了个 ...

  7. toString结果

    String[] str = new String[] { "a", "b", "c" }; System.out.println(str) ...

  8. 2.Android Studio系列教程2——基本设置与运行

    原文链接:http://stormzhang.com/devtools/2014/11/28/android-studio-tutorial2/   一.项目结构   二.Android Studio ...

  9. MSSQL 查询统计某状态出现的次数及累计时间

    1.问题来源 最近客户需要统计某个设备,某状态,在某一个时间段内出现的次数,并计算累计出现的时间. 数据源如下: 现在如果要统计UPSCTSTA状态为D出现的次数(同一状态,连续出现的认为是一次),并 ...

  10. asp.net 定时器

    using System;using System.Collections.Generic;using System.Web;using System.IO;using System.Web.Secu ...