[SPOJ 687]Repeats
Description
题库链接
给出一个长度为 \(n\) 的字符串,求重复次数最多的连续重复子串。
\(1\leq n\leq 50000\)
Solution
Code
#include <bits/stdc++.h>
#define log2 LOG
using namespace std;
const int N = 100000+5, inf = ~0u>>1;char ch[N];
int n, m, x[N<<1], y[N<<1], c[N], sa[N], rk[N], height[N], Case;
int log2[N], bin[30], f[30][N], ans, t;void get() {for (int i = 1; i <= m; i++) c[i] = 0;for (int i = 1; i <= n; i++) c[x[i] = ch[i]]++;for (int i = 2; i <= m; i++) c[i] += c[i-1];for (int i = n; i >= 1; i--) sa[c[x[i]]--] = i;for (int k = 1; k <= n; k <<= 1) {int num = 0;for (int i = n-k+1; i <= n; i++) y[++num] = i;for (int i = 1; i <= n; i++) if (sa[i] > k) y[++num] = sa[i]-k;for (int i = 1; i <= m; i++) c[i] = 0;for (int i = 1; i <= n; i++) c[x[i]]++;for (int i = 2; i <= m; i++) c[i] += c[i-1];for (int i = n; i >= 1; i--) sa[c[x[y[i]]]--] = y[i];swap(x, y); x[sa[1]] = num = 1;for (int i = 2; i <= n; i++)x[sa[i]] = (y[sa[i]] == y[sa[i-1]] && y[sa[i]+k] == y[sa[i-1]+k]) ? num : ++num;if ((m = num) == n) break;}for (int i = 1; i <= n; i++) rk[sa[i]] = i;for (int i = 1, k = 0; i <= n; i++) {if (rk[i] == 1) continue;if (k) --k; int j = sa[rk[i]-1];while (j+k <= n && i+k <= n && ch[i+k] == ch[j+k]) ++k;height[rk[i]] = k;}
}
void rmq() {int t = log2[n];for (int i = 1; i <= n; i++) f[0][i] = height[i];for (int i = 1; i <= t; i++)for (int j = 1; j+bin[i]-1 <= n; j++)f[i][j] = min(f[i-1][j], f[i-1][j+bin[i-1]]);
}
int query(int a, int b) {a = rk[a], b = rk[b];if (a > b) swap(a, b); ++a;int t = log2[b-a+1];return min(f[t][a], f[t][b-bin[t]+1]);
}
void work() {bin[0] = 1; log2[0] = -1;for (int i = 1; i <= 25; i++) bin[i] = (bin[i-1]<<1);for (int i = 1; i < N; i++) log2[i] = log2[i>>1]+1;scanf("%d", &t);while (t--) {scanf("%d", &n); getchar(); m = 255; ans = 0;for (int i = 1; i <= n; i++) scanf("%c", &ch[i]), getchar();get(); rmq();for (int l = 1; l <= n; l++)for (int i = 1; i+l <= n; i += l) {int k = query(i, i+l), t = l-k%l, p = i-t, m = k/l+1;if (p > 0 && query(p+l, p) >= l-k%l) ++m;if (m > ans) ans = m;}printf("%d\n", ans);}
}
int main() {work(); return 0; }
转载于:https://www.cnblogs.com/NaVi-Awson/p/9274228.html
[SPOJ 687]Repeats相关推荐
- 【2012百度之星/资格赛】H:用户请求中的品牌 [后缀数组]
时间限制: 1000ms 内存限制: 65536kB 描述 馅饼同学是一个在百度工作,做用户请求(query)分析的同学,他在用户请求中经常会遇到一些很奇葩的词汇.在比方说"johnsonj ...
- hdu 2459 (后缀数组+RMQ)
题意:让你求一个串中连续重复次数最多的串(不重叠),如果重复的次数一样多的话就输出字典序小的那一串. 分析:有一道比这个简单一些的题spoj 687, 假设一个长度为l的子串重复出现两次,那么它必然会 ...
- 数据结构知识点总结整理
数据结构知识点总结整理 0.常考基础必知必会 A. 排序:排序有几种,各种排序的比较,哪些排序是稳定的,快排的算法: B. 查找:哈希查找.二叉树查找.折半查找的对比,哈希映射和哈希表的区别? C. ...
- 程序员笔试笔记c++
0.常考基础必知必会 A. 排序:排序有几种,各种排序的比较,哪些排序是稳定的,快排的算法: B. 查找:哈希查找.二叉树查找.折半查找的对比,哈希映射和哈希表的区别? C. 链表和数组的区别,在什么 ...
- 程序员笔试知识点整理
程序员笔试知识点整理 0.常考基础必知必会 A. 排序:排序有几种,各种排序的比较,哪些排序是稳定的,快排的算法: B. 查找:哈希查找.二叉树查找.折半查找的对比,哈希映射和哈希表的区别? C. 链 ...
- bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)
Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MB Submit: 7669 Solved: 1894 [Sub ...
- BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster( 后缀数组 + 二分 + RMQ + 树状数组 )
全部串起来做SA, 在按字典序排序的后缀中, 包含每个询问串必定是1段连续的区间, 对每个询问串s二分+RMQ求出包含s的区间. 然后就是求区间的不同的数的个数(经典问题), sort queries ...
- SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并
Can you answer these queries III SPOJ - GSS3 这道题和洛谷的小白逛公园一样的题目. 传送门: 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间 ...
- SPOJ ATOMS - Atoms in the Lab
题目链接:http://www.spoj.com/problems/ATOMS/ 题目大意:有N个原子,他们每秒分裂成K个新原子,新原子也能继续分裂.问如果要控制他的数量为M以内,应在什么时候使其停止 ...
最新文章
- 编译安装LAMP及分离式LAMP平台构建
- python 自动化-Python API 自动化实战详解(纯代码)
- pyinstaller 打包selenium脚本 取消cmd
- 【转】安全测试自学路线图
- 当前最主流的商业模式,普通老板如何打造强大后端实现躺赚的秘诀!
- 对食材的敬畏之心极致产品_这些数据科学产品组合将给您带来敬畏和启发(2020年中的版本)
- Qt creator5.7 OpenCV249之resize函数(含源码下载)
- JeewxBoot微信管家平台源码v1.3
- mysql 慢查询开启
- php获取li或者a标签中间的文字
- 在小榕的论坛看的一篇关于DOS批处理命令的文章
- html微信窗口阻止滚动条,微信浏览器禁止页面下拉查看网址(不影响页面内部scroll)...
- VBA调用程序时,exe程序一闪而过,解决方法
- 传奇私服务器与微端搭建图文说明-- GOM引擎
- 2016山东教师教育网- 一师一优课
- ManoMotion⭐二、Unity手势识别插件简介,及效果录屏
- 后端开发java与php,【后端开发】java与php的区别是什么
- deny后加to do还是doing_常见的后面只能接to do的词组(不能接doing)有哪些
- 最近一直在被螺旋槽成型铣刀的计算折磨着
- JAVA散列表个人通讯录_散列表实现简易通讯录