乐曲主题Musical Themes
SA例题
对于串 \(S\) 的两个子串 \(A\) 和 \(B\) ,满足 \(k = |A| = |B|\),\(\exists c \forall i\, a_i + c=b_i\),且 \(A\) 和 \(B\) 在原串中没有重叠,求最大的满足条件的 \(k\)
先考虑 \(\forall i\, a_i=b_i\) 的情况,二分 \(k\) ,如果在\(height\)上存在一段满足 \(\forall L \le i \le R \,height_i\ge k\),且存在 \(SA[p_1]-SA[p_2] \ge k\),说明 \(k\) 满足条件
接下来将上述做法用在原数组的差分数组上即可,注意判定时条件要改为\(SA[p_1]-SA[p_2] > k\),且要在第一个字符前添加特殊字符,否则判定时可能出问题
#include<cstdio>
using namespace std;
const int MAXN = 5001;
int str[MAXN], sa[MAXN], rank[MAXN], ht[MAXN], buc[MAXN];
void Swap(int*& a, int*& b){
int *tmp = a; a = b; b = tmp;
}
void getSA(int s[], int len){
int *rk = rank, *tp = ht;
int crd = 180, p;
for (int i = 1; i <= len; ++i)
rk[i] = s[i], tp[i] = i;
for (int i = 0; i <= crd; ++i)
buc[i] = 0;
for (int i = 1; i <= len; ++i)
++buc[rk[i]];
for (int i = 1; i <= crd; ++i)
buc[i] += buc[i - 1];
for (int i = len; i >= 1; --i)
sa[buc[rk[tp[i]]]--] = tp[i];
for (int w = 1; p != len; w <<= 1, crd = p){
p = 0;
for (int i = len - w + 1; i <= len; ++i)
tp[++p] = i;
for (int i = 1; i <= len; ++i)
if (sa[i] > w)
tp[++p] = sa[i] - w;
for (int i = 0; i <= crd; ++i)
buc[i] = 0;
for (int i = 1; i <= len; ++i)
++buc[rk[i]];
for (int i = 1; i <= crd; ++i)
buc[i] += buc[i - 1];
for (int i = len; i >= 1; --i)
sa[buc[rk[tp[i]]]--] = tp[i];
Swap(rk, tp);
rk[sa[1]] = p = 1;
for (int i = 2; i <= len; ++i)
rk[sa[i]] = tp[sa[i]] == tp[sa[i - 1]] && tp[sa[i] + w] == tp[sa[i - 1] + w] ? p : ++p;
}
for (int i = 1; i <= len; ++i)
rank[sa[i]] = i;
}
void getHeight(int s[], int len){
ht[1] = 0;
for (int i = 1, j = 0, pos; i <= len; ++i, --j){
if (rank[i] == 1)
continue;
if (j < 0)
j = 0;
pos = sa[rank[i] - 1];
while (s[i + j] == s[pos + j] && i + j <= len && pos + j <= len)
++j;
ht[rank[i]] = j;
}
}
bool judge(int k, int len){
int lp, rp;
for (int i = 1, j; i < len;){
if (ht[i + 1] >= k){
lp = rp = sa[i];
j = i + 1;
while (ht[j] >= k && j <= len){
if (sa[j] < lp)
lp = sa[j];
if (sa[j] > rp)
rp = sa[j];
++j;
}
if (rp - lp > k)
return 1;
i = j;
}
else
++i;
}
return 0;
}
int main(){
int slen;
scanf("%d", &slen);
for (int i = 1, pre = 89, tmp; i <= slen; ++i){
scanf("%d", &tmp);
str[i] = tmp - pre + 89; pre = tmp;
}
getSA(str, slen);
getHeight(str, slen);
int L = 1, R = slen >> 1, mid;
while (L + 1 < R){
mid = L + R >> 1;
if (judge(mid, slen))
L = mid;
else
R = mid;
}
int ans;
if (judge(R, slen))
ans = R;
else
ans = L;
if (ans < 4)
printf("0");
else
printf("%d", ans + 1);
return 0;
}
乐曲主题Musical Themes的更多相关文章
- 洛谷P2743 乐曲主题Musical Themes [USACO5.1] SA
正解:SA 解题报告: 传送门 这题三个条件嘛,那就一个个考虑下都解决了就把这题解决了嘛QwQ 那就直接分别针对三个条件写下各个击破就欧克辣? 1)长度大于等于5:求出答案之后和5比大小 2)不能有公 ...
- Luogu P2743 [USACO5.1]乐曲主题Musical Themes
链接 \(Click\) \(Here\) 人生第一道后缀数组的题目.首先要对输入的串进行差分处理,差分后长度为(\(n - 1\))的相同子段就是原串中长度为\(n\)的相同(可变调)子段.求出来\ ...
- [USACO5.1] 乐曲主题Musical Themes
题目链接:戳我 Emmm......hash怎么做啊不会啊 这里是SA后缀数组版本的 就是先两两做差分,作为要处理后缀的数组.普通地求出来h数组之后,我们二分这个答案,然后判定是否合法就行了.是否合法 ...
- P2743(poj1743) Musical Themes[差分+后缀数组]
P2743 乐曲主题Musical Themes(poj1743) 然后呢这题思路其实还是蛮简单的,只是细节特别多比较恶心,忘记了差分带来的若干疏漏.因为转调的话要保证找到相同主题,只要保证一段内相对 ...
- [转]jQuery EasyUI 扩展-- 主题(Themes)
主题(Themes)允许您改变站点的外观和感观.使用主题可以节省设计的时间,让您腾出更多的时间进行开发.您也可以创建一个已有主题的子主题. 主题生成器(Theme Builder) jQuery UI ...
- USACO Section 5.1 Musical Themes(枚举)
直接枚举O(n^3)会TLE,只要稍微加点优化,在不可能得到更优解时及时退出.其实就是道水题,虽说我提交了6次才过= =..我还太弱了 -------------------------------- ...
- USACO 5.1 Musical Themes(哈希+二分)
Musical ThemesBrian Dean A musical melody is represented as a sequence of N (1 <= N <= 5000) n ...
- Android应用开发中的风格和主题(style,themes)
http://www.cnblogs.com/playing/archive/2011/04/01/2002469.html 越来越多互联网企业都在Android平台上部署其客户端,为了提升用户体验, ...
- [USACO 5.1.3]乐曲主题
Description 我们用N(1 <= N <=5000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,每个数表示钢琴上的一个键.很不幸这种表示旋律的方法忽略了音符的 ...
随机推荐
- 这一篇里面有很多关于scala的list的操作的好的知识
https://www.cnblogs.com/weilunhui/p/5658860.html 1.++[B] 在A元素后面追加B元素 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
- 改进后的向量空间模型(VSM)
我们採用更加形式化的定义,并採用稍大一些的样例来展示怎样使用基于数据集频率的权重.相应于一个给定的词项,其权重使用IDF(逆文档频率)来计算. 为了给每篇文档建立一个相应的向量,能够考虑例如以下定义. ...
- vue 给组件绑定原生事件
有时候,你可能想在某个组件的根元素上监听一个原生事件.可以使用 v-on 的修饰符 .native.例如: <my-component v-on:click.native="doThe ...
- 使用match、test控制输入字符格式后键盘向左向右键光标自动定位解决
直接举例说明(正则表达式替换红色区域即可) /** * 判断是否位数字 * @param obj 数字 */ function numOnly(obj) { if(!(/^\d*$/.test(obj ...
- 使用Android注解来改善代码
昨晚看到一篇好文章.然后是英文的.所以决定翻译分享给大家.这是原文链接:http://www.michaelevans.org/blog/2015/07/14/improving-your-code- ...
- python(10)- 字符编码
一 什么是编码? 基本概念很简单.首先,我们从一段信息即消息说起,消息以人类可以理解.易懂的表示存在.我打算将这种表示称为“明文”(plain text).对于说英语的人,纸张上打印的或屏幕上显示的英 ...
- Web框架Django(二)
一.Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层 ...
- 做QA的日子——iOS測试入门(四)
坦言,做QA的这半年我没有成长,就算有成长也非常少,我非常难过.和身边的人讲事实上并没有谁能真正理解自己的难过,事实上还是自己不够努力.对自己不够狠,以前认为自己不够幸运,想有一个更好的指路人,事实上 ...
- 【每日Scrum】第三天(4.13) TD学生助手Sprint1站立会议
TD学生助手Sprint1站立会议(4.13) 任务看板 站立会议内容 组员 昨天 今天 困难 签到 刘铸辉 (组长) 昨天完成了课程的增删改查功能 今天早晨静姐调整了下界面和配色,下午和宝月兄一起做 ...
- Django-中介模型
有多对多字段的时候自己创建的第三章表就是中介模型 class Article(models.Model): ''' 文章表 ''' title = models.CharField(max_lengt ...