Brief Description

给定一个字符串,求至少出现k次的最长重复子串。

Algorithm Design

先二分答案,然后将后缀分成若干组。判断有没有一个组的后缀个数不小于k。如果有,那么存在k个相同的子串满足条件,否则不存在。这个做法的时间复杂度为\(\Theta(nlgn)\).

Code

#include <cstdio>
const int maxn = 20010;
int a[maxn], sa[2][maxn], rank[2][maxn], height[maxn];
int n, K, k, m, p, q;
int v[1000100];
void calc(int sa[maxn], int rank[maxn], int Sa[maxn], int Rank[maxn]) {
for (int i = 1; i <= n; i++)
v[rank[sa[i]]] = i;
for (int i = n; i >= 1; i--)
if (sa[i] > k)
Sa[v[rank[sa[i] - k]]--] = sa[i] - k;
for (int i = n - k + 1; i <= n; i++)
Sa[v[rank[i]]--] = i;
for (int i = 1; i <= n; i++)
Rank[Sa[i]] = Rank[Sa[i - 1]] + (rank[Sa[i]] != rank[Sa[i - 1]] ||
rank[Sa[i] + k] != rank[Sa[i - 1] + k]);
}
void calh(int sa[maxn], int rank[maxn]) {
int i, j, k = 0;
for (i = 1; i <= n; height[rank[i++]] = k)
for (k ? k-- : 0, j = sa[rank[i] - 1]; a[i + k] == a[j + k]; k++)
;
return;
}
void da() {
m = 1000010, p = 0, q = 1, k = 1;
for (int i = 1; i <= n; i++)
v[a[i]]++;
for (int i = 1; i <= m; i++)
v[i] += v[i - 1];
for (int i = 1; i <= n; i++)
sa[p][v[a[i]]--] = i;
for (int i = 1; i <= n; i++)
rank[p][sa[p][i]] =
rank[p][sa[p][i - 1]] + (a[sa[p][i - 1]] != a[sa[p][i]]);
while (k < n) {
calc(sa[p], rank[p], sa[q], rank[q]);
p ^= 1;
q ^= 1;
k <<= 1;
}
calh(sa[p], rank[p]);
}
bool check(int x) {
int l = 1, r = 1;
for (int i = 2; i <= n + 1; i++)
if (height[i] >= x)
r++;
else if (r - l + 1 >= K)
return true;
else {
l = i;
r = i;
continue;
}
return false;
}
void solve() {
int l = 0, r = n;
while (r - l > 1) {
int mid = (l + r) >> 1;
if (check(mid))
l = mid;
else
r = mid;
}
printf("%d\n", check(r) ? r : l);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input", "r", stdin);
#endif
scanf("%d %d", &n, &K);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
da();
solve();
}

[bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式——后缀数组的更多相关文章

  1. bzoj1717: [Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+二分)

    /* 求可重叠的至少重复K次的最长字串 以1为下标起点,因为a[i]最大到1000000,所以要先离散一下 二分长度len 然后O(n)检验 后看h[i]是否有连续的一段h[i]大于len的,并且h[ ...

  2. BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 [后缀数组]

    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1017  Solved: ...

  3. 【BZOJ1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 后缀数组

    [BZOJ1717][Usaco2006 Dec]Milk Patterns Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量 ...

  4. 【bzoj1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 后缀数组+离散化

    题目描述 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个“模式”. John的牛奶按质量可以被赋予一 ...

  5. bzoj1717: [Usaco2006 Dec]Milk Patterns 产奶的模式

    后缀数组+二分答案+离散化.(上次写的时候看数据小没离散化然后一直WA...写了lsj师兄的写法. #include<cstdio> #include<cstring> #in ...

  6. [bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式_后缀数组_二分答案

    Milk Patterns 产奶的模式 bzoj-1717 Usaco-2006 Dec 题目大意:给定一个字符串,求最长的至少出现了$k$次的子串长度. 注释:$1\le n\le 2\cdot 1 ...

  7. [bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式 (hash构造后缀数组,二分答案)

    以后似乎终于不用去学后缀数组的倍增搞法||DC3等blablaSXBK的方法了= = 定义(来自关于后缀数组的那篇国家集训队论文..) 后缀数组:后缀数组SA是一个一维数组,它保存1..n的某个排列S ...

  8. BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式( 二分答案 + 后缀数组 )

    二分答案m, 后缀数组求出height数组后分组来判断. ------------------------------------------------------------ #include&l ...

  9. BZOJ#1717:[Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+单调队列)

    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的 ...

随机推荐

  1. 「暑期训练」「Brute Force」 Multiplication Table (CFR256D2D)

    题意 给定一矩阵M" role="presentation">MM,Mij=ij" role="presentation">Mi ...

  2. 虚拟现实-VR-UE4-编译UE4源码

    通过Git将UE4源代码获取到本地计算机 切记路径不要有中文 这里面我已经在进行编译了,有部分文件是多余出来的, 第一步就是点击 setup.bat批处理,这个过程回取决与你的网速的快慢,我等了一下午 ...

  3. Android Spiner实现Key-Value

    原网址:http://www.eoeandroid.com/thread-29687-1-1.html?_dsign=02d5cd6a 学习到的方法,直接上代码了: 1.定义一个class publi ...

  4. 深度学习-CNN tensorflow 可视化

    tf.summary模块的简介 在TensorFlow中,最常用的可视化方法有三种途径,分别为TensorFlow与OpenCv的混合编程.利用Matpltlib进行可视化.利用TensorFlow自 ...

  5. Python登录小程序

    ------------------------------------------------- 主要实现功能 1.用户输入用户名,在用户名文件中查找对应的用户,若无对应用户名则打印输入错误 2.用 ...

  6. 关于c++的头文件依赖

    正在看google c++编程规范,里面对头文件依赖是这么说的: 使用前置声明(forward declarations)尽量减少.h文件中#include的数量. 当一个头文件被包含的同时也引入了一 ...

  7. 【集训试题】exam 信心考 最小割

    题意概述: 有N个人,A,B两个考场.如果学生i在A考场,总信心值增加xi:如果学生i在B考场,总信心值增加yi.其中还有m对好友,当第i对好友的两个人都在A考场时,总信心值增加ai:如果两人都在B考 ...

  8. 使用ZSetOperations(有序)操作redis

    方法 c参数 s说明 Boolean add(K key, V value, double score); K key:集合key V value:key对应的值 double score:分数  向 ...

  9. MySQL初始4--去重

    更新表中的字段: update 表名 set 字段=新值,… where 条件: UPDATE语法可以用新值更新原有表行中的各列.SET子句指示要修改哪些列和要给予哪些值.WHERE子句指定应更新哪些 ...

  10. 搭建Elasticsearch 5.4分布式集群

    多机集群中的节点可以分为master nodes和data nodes,在配置文件中使用Zen发现(Zen discovery)机制来管理不同节点.Zen发现是ES自带的默认发现机制,使用多播发现其它 ...