[USACO5.1] Musical Themes
后缀数组求最长重复且不重叠子串。
1.子串可以“变调”(即1 3 6和3 5 8视作相同)。解决办法:求字符串相邻元素的差形成新串。用新字符串求解最长重复子串即可。
2.最长重复子串不能重叠。解决办法:用sa数组判断开始位置。
倍增答案即可,从1到n枚举height,记录子串开始的最左端、最右端。
如果找到了两个后缀,其公共前缀长度大于k,且其开始位置之间的间隔大于k,就满足条件。
由height数组的性质可得:要使x、y的公共前缀长度大于k,则需要h[x+1]、h[x+2]......h[y]全部大于k。
所以只要有一个没有大于k,就得重新开始。即:重置子串开始的最左端、最右端。
最后答案需要+1,并判断是否大于等于5(题意要求)。
注意poj的数据范围比洛谷上大,而且有多组测试数据。
下面只给出poj1743的代码。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; int n,ans;
int s[];
int sa[],rk[];
int tr[],h[]; int cmp(int x,int y,int k)
{
if(x+k>n||y+k>n)return ;
return rk[x]==rk[y]&&rk[x+k]==rk[y+k];
} void cal()
{
int i,cnt;
for(i=;i<=n;i++)h[s[i]]++;
for(cnt=,i=;i<=;i++)if(h[i])tr[i]=++cnt;
for(i=;i<=;i++)h[i]+=h[i-];
for(i=;i<=n;i++)rk[i]=tr[s[i]],sa[h[s[i]]--]=i;
for(int k=;cnt!=n;k<<=)
{
for(i=;i<=n;i++)h[i]=;
for(i=;i<=n;i++)h[rk[i]]++;
for(i=;i<=n;i++)h[i]+=h[i-];
for(i=n;i;i--)if(sa[i]>k)tr[sa[i]-k]=h[rk[sa[i]-k]]--;
for(i=;i<=k;i++)tr[n-i+]=h[rk[n-i+]]--;
for(i=;i<=n;i++)sa[tr[i]]=i;
for(cnt=,i=;i<=n;i++)tr[sa[i]]=cmp(sa[i],sa[i-],k)?cnt:++cnt;
for(i=;i<=n;i++)rk[i]=tr[i];
}
for(i=;i<=n;i++)h[i]=;
for(i=;i<=n;i++)
{
if(rk[i]==)continue;
for(int j=max(,h[rk[i-]]-);;j++)
{
if(s[i+j-]==s[sa[rk[i]-]+j-])h[rk[i]]=j;
else break;
}
}
} int check(int k)
{
if(k>n)return ;
int l,r;
l=r=sa[];
for(int i=;i<=n;i++)
{
if(h[i]>=k)
{
l=min(l,sa[i]);
r=max(r,sa[i]);
if(r-l>k)return ;
}else l=r=sa[i];
}
return ;
} int main()
{
scanf("%d",&n);
while(n)
{
memset(h,,sizeof(h));
memset(tr,,sizeof(tr));
memset(rk,,sizeof(rk));
memset(sa,,sizeof(sa));
ans=;
for(int i=;i<=n;i++)scanf("%d",&s[i]);
for(int i=;i<n;i++)s[i]=s[i+]-s[i]+;
cal();
for(int i=;i>=;i--)
if(check(ans|(<<i)))ans|=(<<i);
ans=(ans+)>=?(ans+):;
printf("%d\n",ans);
scanf("%d",&n);
}
return ;
}
[USACO5.1] Musical Themes的更多相关文章
- 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 ...
- P2743(poj1743) Musical Themes[差分+后缀数组]
P2743 乐曲主题Musical Themes(poj1743) 然后呢这题思路其实还是蛮简单的,只是细节特别多比较恶心,忘记了差分带来的若干疏漏.因为转调的话要保证找到相同主题,只要保证一段内相对 ...
- Luogu P2743 [USACO5.1]乐曲主题Musical Themes
链接 \(Click\) \(Here\) 人生第一道后缀数组的题目.首先要对输入的串进行差分处理,差分后长度为(\(n - 1\))的相同子段就是原串中长度为\(n\)的相同(可变调)子段.求出来\ ...
- 洛谷P2743 乐曲主题Musical Themes [USACO5.1] SA
正解:SA 解题报告: 传送门 这题三个条件嘛,那就一个个考虑下都解决了就把这题解决了嘛QwQ 那就直接分别针对三个条件写下各个击破就欧克辣? 1)长度大于等于5:求出答案之后和5比大小 2)不能有公 ...
- [USACO5.1] 乐曲主题Musical Themes
题目链接:戳我 Emmm......hash怎么做啊不会啊 这里是SA后缀数组版本的 就是先两两做差分,作为要处理后缀的数组.普通地求出来h数组之后,我们二分这个答案,然后判定是否合法就行了.是否合法 ...
- 乐曲主题Musical Themes
SA例题 题面 对于串 \(S\) 的两个子串 \(A\) 和 \(B\) ,满足 \(k = |A| = |B|\),\(\exists c \forall i\, a_i + c=b_i\),且 ...
- POJ 1743 [USACO5.1] Musical Theme (后缀数组+二分)
洛谷P2743传送门 题目大意:给你一个序列,求其中最长的一对相似等长子串 一对合法的相似子串被定义为: 1.任意一个子串长度都大于等于5 2.不能有重叠部分 3.其中一个子串可以在全部+/-某个值后 ...
- 学校作业-Usaco DP水题
好吧,因为USACO挂掉了,所以我写的所有代码都不保证正确性[好的,这么简单的题,再不写对,你就可以滚粗了! 第一题是USACO 2.2.2 ★Subset Sums 集合 对于从 1 到 N 的连 ...
随机推荐
- Kattis dragonball1 Dragon Ball I(最短路)
There is a legendary tale about Dragon Balls on Planet X: if one collects seven Dragon Balls, the Dr ...
- Django知识点_梳理
- 获取IP和IP地址
<script src="http://pv.sohu.com/cityjson?ie=utf-8"></script>; <script type= ...
- <黑马新秀>Spring学习日志
# 用于梳理Spring知识点 Spring是分层的Java EE应用全栈轻量级开源框架,以IoC(Inverse Of Control反转控制)和AOP(Aspect Oriented Progra ...
- [GX/GZOI2019]特技飞行(扫描线+置换)
感觉是6题中最难的一题,其实这题是一个二合一: 第一问:给定平面上若干点和k个关键点,关键点覆盖一个45°倾斜的正方形范围r,求有多少点被至少一个关键点覆盖.这个可以曼哈顿转切比雪夫距离,然后再扫描线 ...
- echarts 实现柱状图重叠而不是相互增加
1.引入echart 所需要的js和css,这不再引入 总量的数据是包含分量且大于等于分量 先上效果图: 当我们查看总量时,显示的是将分量的也包含里面,这样就不是叠加的数量了 2.直接上代码 (可复制 ...
- nginx简单安装
虚拟机首先要求ping www.baidu.com 下载: 解压: 创建用户: [root@nginx ~]# useradd -M -s /sbin/nologin nginx-M 不创建加目录 ...
- 20)PHP,数组的遍历
然后开始使用这2个函数和while循环结构来实现数组遍历: 形式: reset($arr1); while ( list ($key, $value ) = each( $arr1) ) //从数组$ ...
- python之urllib模块和requests模块
一.urllib模块 python标准库自带的发送网络请求的模块. # 用python怎么打开浏览器,发送接口请求 import urllib from urllib.request import u ...
- bzoj 3450 Tyvj1952 Easy (概率dp)
3450: Tyvj1952 Easy Description 某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:(我们来简化一下这个游戏的规则有n次点击要做,成功了就是o,失败 ...