后缀数组求最长重复且不重叠子串。

poj 1743 传送门

洛谷 P2743 传送门

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的更多相关文章

  1. USACO Section 5.1 Musical Themes(枚举)

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

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

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

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

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

  4. Luogu P2743 [USACO5.1]乐曲主题Musical Themes

    链接 \(Click\) \(Here\) 人生第一道后缀数组的题目.首先要对输入的串进行差分处理,差分后长度为(\(n - 1\))的相同子段就是原串中长度为\(n\)的相同(可变调)子段.求出来\ ...

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

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

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

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

  7. 乐曲主题Musical Themes

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

  8. POJ 1743 [USACO5.1] Musical Theme (后缀数组+二分)

    洛谷P2743传送门 题目大意:给你一个序列,求其中最长的一对相似等长子串 一对合法的相似子串被定义为: 1.任意一个子串长度都大于等于5 2.不能有重叠部分 3.其中一个子串可以在全部+/-某个值后 ...

  9. 学校作业-Usaco DP水题

    好吧,因为USACO挂掉了,所以我写的所有代码都不保证正确性[好的,这么简单的题,再不写对,你就可以滚粗了! 第一题是USACO 2.2.2 ★Subset Sums 集合  对于从 1 到 N 的连 ...

随机推荐

  1. 201503-1 图像旋转 Java

    思路: 观察输入和输出可以发现,第三列输出为第一行,第二列输出为第二行,第一列输出为第三行.循环即可 import java.util.Scanner; //得分80,本题最高需要输入100W次,因为 ...

  2. Struts 2 的常规配置

    Struts 2 的默认配置文件是struts.xml,该文件应该放在Web应用的类加载路径下,通常就是放在WEB-INF/classes路径下. struts.xml文件的最大作用是配置Action ...

  3. 吴裕雄--天生自然Linux操作系统:Linux 系统目录结构

    登录系统后,在当前命令窗口下输入命令: ls / 你会看到如下图所示: 树状目录结构: 以下是对这些目录的解释: /bin:bin是Binary的缩写, 这个目录存放着最经常使用的命令. /boot: ...

  4. java使用io流读取windows文件乱码问题

    出现原因: 在IDEA中,使用 FileReader 读取项目中的文本文件.由于IDEA的设置,都是默认的 UTF-8 编码,所以没有任何 问题. 但是,当读取Windows系统中创建的文本文件时,由 ...

  5. tensroflow中如何计算特征图的输出及padding大小

    根据tensorflow中的conv2d函数,我们先定义几个基本符号 1.输入矩阵 W×W,这里只考虑输入宽高相等的情况,如果不相等,推导方法一样,不多解释. 2.filter矩阵 F×F,卷积核 3 ...

  6. 关于使用静态链表实现一元多项式的相加&&乘积

    一元多项式的相加类似于两条链表的合并 当然前提是链表中的幂指数是按顺序排列的 此题中的链表采用的是升序排列,输出也是按升序输出的 #include<stdio.h> #include< ...

  7. CodeForces 992B Nastya Studies Informatics + Hankson的趣味题(gcd、lcm)

    http://codeforces.com/problemset/problem/992/B  题意: 给你区间[l,r]和x,y 问你区间中有多少个数对 (a,b) 使得 gcd(a,b)=x lc ...

  8. 吴裕雄--天生自然 pythonTensorFlow自然语言处理:Attention模型--训练

    import tensorflow as tf # 1.参数设置. # 假设输入数据已经转换成了单词编号的格式. SRC_TRAIN_DATA = "F:\\TensorFlowGoogle ...

  9. 如何查看iOS系统版本在iPhone设备上的占有率

    我们平时开发的时候有时要考虑到系统的兼容版本,但是怎么知道各个版本的系统占有率,其实这个苹果官方是有提供的.进入如下链接到的页面就可以知道各大系统版本的占有率了,不过说实在的iPhone用户的系统更新 ...

  10. The website is API(4)

    1.淘宝商品信息定向爬虫 目标:获取淘宝搜索页面信息,提取其中的商品名称和价格 理解:淘宝的搜索接口 翻页的处理 技术路线:requests+re https://s.taobao.com/searc ...