链接 \(Click\) \(Here\)

人生第一道后缀数组的题目。首先要对输入的串进行差分处理,差分后长度为(\(n - 1\))的相同子段就是原串中长度为\(n\)的相同(可变调)子段。求出来\(height\)以后,二分一个最大不相交重复子段长度,在\(can\_use\)里面维护长度为\(k\)的段划分,判断不相交只要用\(sa\)的差值算一下长度就好。

\(p.s.\)细节真的很多。

#include <bits/stdc++.h>
using namespace std; const int N = 5010; int n, m = 255, s[N], sa[N], rk[N], tp[N], _rk[N], bin[N], height[N]; 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 () {
for (int i = 1; i <= n; ++i) {
rk[i] = s[i];
tp[i] = 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;
}
} void get_height () {
int k = 0;
for (int i = 1; i <= n; ++i) {
if (k != 0) k = k - 1;
int j = sa[rk[i] - 1];
while (s[i + k] == s[j + k]) {
k = k + 1;
}
height[rk[i]] = k;
}
} const int INF = 0x3f3f3f3f; bool can_use (int k) {
//是否有长度>=k的不交叉子串
int max_sa = sa[1], min_sa = sa[1];
for (int i = 2; i <= n; ++i) {
if (height[i] >= (k - 1)) {
//即原串中旋律长度 >= k
max_sa = max (max_sa, sa[i]);
min_sa = min (min_sa, sa[i]);
if (max_sa - min_sa >= k) {
return true;
}
} else {
max_sa = sa[i];
min_sa = sa[i];
}
}
return false;
} int main () {
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> s[i];
}
for (int i = n; i >= 1; --i) {
s[i] = s[i] - s[i - 1] + 90;
//把s差分,出现n-1个相同项说明最长为n
}
// printf ("str Test : "); for (int i = 1; i <= n; ++i) printf ("%3d ", s[i]); putchar ('\n');
suffix_sort ();
get_height ();
// printf ("height Test : "); for (int i = 1; i <= n; ++i) printf ("%3d ", height[i]); printf ("\n");
int l = 0, r = n;
while (l < r) {
// printf ("l = %d, r = %d\n", l, r);
int mid = (l + r + 1) >> 1;
if (can_use (mid)) {
//存在长度 >= mid的不交叉子串
l = mid;
} else {
r = mid - 1;
}
}
if (l < 5) printf ("0\n");
else printf ("%d\n", l);
}

Luogu P2743 [USACO5.1]乐曲主题Musical Themes的更多相关文章

  1. [USACO5.1] 乐曲主题Musical Themes

    题目链接:戳我 Emmm......hash怎么做啊不会啊 这里是SA后缀数组版本的 就是先两两做差分,作为要处理后缀的数组.普通地求出来h数组之后,我们二分这个答案,然后判定是否合法就行了.是否合法 ...

  2. 洛谷P2743 乐曲主题Musical Themes [USACO5.1] SA

    正解:SA 解题报告: 传送门 这题三个条件嘛,那就一个个考虑下都解决了就把这题解决了嘛QwQ 那就直接分别针对三个条件写下各个击破就欧克辣? 1)长度大于等于5:求出答案之后和5比大小 2)不能有公 ...

  3. 乐曲主题Musical Themes

    SA例题 题面 对于串 \(S\) 的两个子串 \(A\) 和 \(B\) ,满足 \(k = |A| = |B|\),\(\exists c \forall i\, a_i + c=b_i\),且 ...

  4. P2743(poj1743) Musical Themes[差分+后缀数组]

    P2743 乐曲主题Musical Themes(poj1743) 然后呢这题思路其实还是蛮简单的,只是细节特别多比较恶心,忘记了差分带来的若干疏漏.因为转调的话要保证找到相同主题,只要保证一段内相对 ...

  5. [转]jQuery EasyUI 扩展-- 主题(Themes)

    主题(Themes)允许您改变站点的外观和感观.使用主题可以节省设计的时间,让您腾出更多的时间进行开发.您也可以创建一个已有主题的子主题. 主题生成器(Theme Builder) jQuery UI ...

  6. USACO Section 5.1 Musical Themes(枚举)

    直接枚举O(n^3)会TLE,只要稍微加点优化,在不可能得到更优解时及时退出.其实就是道水题,虽说我提交了6次才过= =..我还太弱了 -------------------------------- ...

  7. USACO 5.1 Musical Themes(哈希+二分)

    Musical ThemesBrian Dean A musical melody is represented as a sequence of N (1 <= N <= 5000) n ...

  8. [Luogu P1345] [USACO5.4]奶牛的电信Telecowmunication (最小割)

    题面 传送门:https://www.luogu.org/problemnew/show/P1345 ] Solution 这道题,需要一个小技巧了解决. 我相信很多像我这样接蒟蒻,看到这道题,不禁兴 ...

  9. [USACO5.1] Musical Themes

    后缀数组求最长重复且不重叠子串. poj 1743 传送门 洛谷 P2743 传送门 1.子串可以“变调”(即1 3 6和3 5 8视作相同).解决办法:求字符串相邻元素的差形成新串.用新字符串求解最 ...

随机推荐

  1. TP5上传图片

    模板: <form action="{:url('Temp/addTempDo')}" enctype="multipart/form-data" met ...

  2. Error:Failed to resolve: com.android.support:appcompat-v7

    repositories { maven { url "https://maven.google.com" } } implementation 'com.android.supp ...

  3. model,map,MapAndVivew用于页面跳转时候使用的即跳转后才添加属性 这样再回调中无法使用 因为回调的前提是页面不调转;解决的方法是用responsewrite(普通的字符响应)

    model,map,MapAndVivew用于页面跳转时候使用的即跳转后才添加属性 这样再回调中无法使用 因为回调的前提是页面不调转:解决的方法是用responsewrite

  4. poj-2752(拓展kmp)

    题意:求一个串所有的前后缀字串: 解题思路:kmp和拓展kmp都行,个人感觉拓展kmp更裸一点: 拓展kmp: #include<iostream> #include<algorit ...

  5. codevs2822

    解题思路: tarjan缩点后算出度为0的点有几个,如果只有一个且这个点为爱心天使就行了: #include<iostream> #include<algorithm> #in ...

  6. 【CPU】理解CPU

    CPU,全称Central Processing Unit,即中央处理器. 何为CPU? 计算机必须能够自动地从主存中取出一条条指令执行,专门来执行指令的就是CPU. 一.指令的执行过程 为了理解CP ...

  7. Bootstrap modal 模态框垂直居中显示补丁

    <script> $.fn.modal.Constructor.prototype.adjustDialog1 = function(){ var modalIsOverflowing = ...

  8. 使用RestTemplate测试视频上传的Post请求

    以往多用RestTemplate处理接口的调用以及与Ribbon/Feign配合使用调用微服务接口,近日写了一个处理Post文件上传的解决方案,其实就是将后台所需的MultipartFile,在请求P ...

  9. JQ用法

    jQuery简称jq,是一款同prototype一样优秀js开发库类,特别是对css和XPath的支持,使我们写js变得更加方便!如果你不是个js高手又想写出优 秀的js效果,jq可以帮你达到目的!下 ...

  10. centos 7创建ss服务(方式二)

    一:安装pip yum install python-pip 如果没有python包则执行命令:yum -y install epel-release: 二:安装SS pip install shad ...