给定字符串,求重复次数最多的连续重复子串。

题目很简单,被细节坑惨了。。。

前置的一个推论:请看这里。

#include <bits/stdc++.h>
using namespace std; const int N = 50010; struct String {
char s[N]; int st[N][17]; int n, m, sa[N], tp[N], rk[N], _rk[N], bin[N], height[N]; void clear () {
memset (s, 0, sizeof (s));
memset (sa, 0, sizeof (sa));
memset (tp, 0, sizeof (tp));
memset (rk, 0, sizeof (rk));
memset (st, 0, sizeof (st));
memset (_rk, 0, sizeof (_rk));
memset (bin, 0, sizeof (bin));
memset (height, 0, sizeof (height));
} void base_sort () {
for (int i = 0; i <= m; ++i) bin[i] = 0;
for (int i = 1; i <= n; ++i) bin[rk[tp[i]]]++;
for (int i = 1; i <= m; ++i) bin[i] += bin[i - 1];
for (int i = n; i >= 1; --i) sa[bin[rk[tp[i]]]--] = tp[i];
} void suffix_sort () {
m = 255; ;
for (int i = 1; i <= n; ++i) {
tp[i] = i, rk[i] = s[i];
}
base_sort ();
for (int w = 1; w <= n; w <<= 1) {
int cnt = 0;
for (int i = n - w + 1; i <= n; ++i) tp[++cnt] = i;
for (int i = 1; i <= n; ++i) if (sa[i] > w) tp[++cnt] = sa[i] - w;
base_sort ();
memcpy (_rk, rk, sizeof (rk));
rk[sa[1]] = cnt = 1;
for (int i = 2; i <= n; ++i) {
rk[sa[i]] = _rk[sa[i]] == _rk[sa[i - 1]] && _rk[sa[i] + w] == _rk[sa[i - 1] + w] ? cnt : ++cnt;
}
if (cnt == n) break;
m = cnt;
}
int k = 0;
for (int i = 1; i <= n; ++i) {
if (k != 0) --k;
int j = sa[rk[i] - 1];
while (s[i + k] == s[j + k]) ++k;
height[rk[i]] = k;
}
int mx = log2 (n);
for (int i = 1; i <= n; ++i) {
st[i][0] = height[i];
}
for (int i = 1; i <= mx; ++i) {
for (int j = 1; j + (1 << i) - 1 <= n; ++j) {
st[j][i] = min (st[j][i - 1], st[j + (1 << (i - 1))][i - 1]);
}
}
} int lcp (int l, int r) {
if (l == r) return n - l + 1;
l = rk[l], r = rk[r];
if (l > r) swap (l, r); ++l;
if (l > r) return 0;
int mx = log2 (r - l + 1);
return min (st[l][mx], st[r - (1 << mx) + 1][mx]);
}
}s1, s2; int T, n; char s[N]; int main () {
cin >> T;
while (T--) {
int ans = 0;
cin >> n; s1.n = s2.n = n;
s1.clear (); s2.clear ();
for (int i = 1; i <= n; ++i) {
cin >> s[i];
s1.s[i] = s[i];
s2.s[n - i + 1] = s[i];
}
s1.suffix_sort ();
s2.suffix_sort ();
for (int len = 1; len <= n; ++len) {//枚举重复子串的长度
for (int p = 1; p + len <= n; p += len) {
int K = s1.lcp (p, p + len) + s2.lcp (n - (p) + 1, n - (p + len) + 1) - 1;
ans = max (ans, K / len + 1);
}
}
cout << max (ans, 1) << endl;
}
}

SP687 REPEATS - Repeats的更多相关文章

  1. SP687 REPEATS - Repeats(后缀数组)

    一个初步的想法是我们枚举重复子串的长度\(L\).然后跑一遍SA.然后我们枚举一个点\(i\),令他的对应点为\(i+L\),然后求出这两个点的LCP和LCS的长度答案就是这个点的答案就是\((len ...

  2. 题解 SP687 【REPEATS - Repeats】

    考虑可以枚举字符串上的两个点,求出两个点所对应后缀的\(LCP\)和所对应前缀的\(LCS\),两点之间的距离为\(len\),则这两个点对答案的贡献为: \[ \frac{LCS+LCP+L-1}{ ...

  3. SPOJ - REPEATS Repeats (后缀数组)

    A string s is called an (k,l)-repeat if s is obtained by concatenating k>=1 times some seed strin ...

  4. spoj687 REPEATS - Repeats (后缀数组+rmq)

    A string s is called an (k,l)-repeat if s is obtained by concatenating k>=1 times some seed strin ...

  5. SPOJ REPEATS Repeats (后缀数组 + RMQ:子串的最大循环节)题解

    题意: 给定一个串\(s\),\(s\)必有一个最大循环节的连续子串\(ss\),问最大循环次数是多少 思路: 我们可以知道,如果一个长度为\(L\)的子串连续出现了两次及以上,那么必然会存在\(s[ ...

  6. SPOJ 687 REPEATS - Repeats

    题意 给定字符串,求重复次数最多的连续重复子串 思路 后缀数组的神题 让我对着题解想了快1天 首先考虑一个暴力,枚举循环串的长度l,然后再枚举每个点i,用i和i+l匹配,如果匹配长度是L,这个循环串就 ...

  7. SPOJ - REPEATS Repeats (后缀数组+RMQ)

    题意:求一个串中出现重复子串次数最多的数目. 析:枚举每个长度的子串,至少要重复两次,必然会经过s[l*i]中相邻的两个,然后再分别向前和向后匹配即可. 代码如下: #pragma comment(l ...

  8. SPOJ Repeats(后缀数组+RMQ-ST)

    REPEATS - Repeats no tags  A string s is called an (k,l)-repeat if s is obtained by concatenating k& ...

  9. SPOJ - REPEATS —— 后缀数组 重复次数最多的连续重复子串

    题目链接:https://vjudge.net/problem/SPOJ-REPEATS REPEATS - Repeats no tags  A string s is called an (k,l ...

随机推荐

  1. 前后端分离djangorestframework—— 接入支付宝支付平台

    支付宝 简介 支付宝是什么不用多说了,本次教程适合初学者 前提准备 话不多说,干就完了 1.注册开发者账号,设置公钥私钥 首先进入支付宝开发者平台:传送门 ,有账号直接登录,没账号用你平时用来付款收钱 ...

  2. 网络编程中TCP基础巩固以及Linux打开的文件过多文件句柄的总结

    1.TCP连接(短链接和长连接) 什么是TCP连接?TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议. 当网络通信 ...

  3. selenium Python 总结一些工作中可能会经常使用到的API。

    selenium Python 总结一些工作中可能会经常使用到的API. 1.获取当前页面的Url 方法:current_url 实例:driver.current_url 2.获取元素坐标 方法:l ...

  4. Java开发学习心得(二):Mybatis和Url路由

    目录 Java开发学习心得(二):Mybatis和Url路由 1.3 Mybatis 2 URL路由 2.1 @RequestMapping 2.2 @PathVariable 2.3 不同的请求类型 ...

  5. IDF-简单题目writeup

    1. 被改错的密码 原题: 从前有一个熊孩子入侵了一个网站的[数据库],找到了管理员密码,手一抖在[数据库]中修改了一下,现在的密码变成了ca9cc444e64c8116a30la00559c042b ...

  6. nginx报错:failed (13: Permission denied)

    vim nginx.conf 修改user nginx为当前系统用户,如:user root

  7. 基于C#的钉钉SDK开发(1)--对官方SDK的重构优化

    在前段时间,接触一个很喜欢钉钉并且已在内部场景广泛使用钉钉进行工厂内部管理的客户,如钉钉考勤.日常审批.钉钉投影.钉钉门禁等等方面,才体会到原来钉钉已经已经在企业上可以用的很广泛的,因此回过头来学习研 ...

  8. 你不知道的 requestIdleCallback

    本文副标题是 Request Schedule 源码解析一.在本章中会介绍 requestIdleCallback 的用法以及其缺陷, 接着对 React 团队对该 api 的 hack 部分的源码进 ...

  9. android_模拟器调试

    找到adb_server adb_server connect

  10. C#直接使用DllImport调用C/C++动态库(dll文件)

    1.C/C++动态库的编写 下面是我编写的一个比较简单的C++dll文件用来测试,关于如何编写dll文件,我这里便不再赘述,不懂得自行查询, (1).h文件 #ifdef MYDLL_EXPORTS ...