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

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. VCRedist_x86.exe Vcredist_x64.exe

    Update for Visual C++ 2013 and Visual C++ Redistributable Package https://support.microsoft.com/en-u ...

  2. webview Java与JS互调

    Android调用JS:方法一 webView.loadUrl("javascript:show('"+info+"')"); Android调用JS:方法二 ...

  3. 长沙中考2019数学T25讲解

    好久没更Blog了... 为了应付完成寒假作业,还是更一下(再不更都庚子年了) Upd:2020.1.22 题目 第一问 还是比较水友好的 给顶点就相当于多给了对称轴-\(\frac{b}{2a}\) ...

  4. zxing生成二维码转base64 img直接显示 Image对象转Base64码(java)

    public static String encodeToBase64(String content){ MultiFormatWriter multiFormatWriter = new Multi ...

  5. 刷题34. Find First and Last Position of Element in Sorted Array

    一.题目说明 题目是34. Find First and Last Position of Element in Sorted Array,查找一个给定值的起止位置,时间复杂度要求是Olog(n).题 ...

  6. drf三大认证补充

    频率认证 源码分析部分 def check_throttles(self, request): for throttle in self.get_throttles(): if not throttl ...

  7. php利用curl发送 post get del put patch 请求

    因为需要在php开发中对接其它接口需要用php  curl去对接其它接口  我把他们封装成函数 希望能对大家有所帮助 这里面是封装好的  会自动把data进行转成json格式   同时解码成php数组 ...

  8. Perl: 单引号里面的直接给当做标量了,而直接输出($`)的话就是变量值,即相符段落的前置字符会存到这里。输出‘$`’ 就变成标量值了

    print '$`'."\n";print '$&'."\n";print $'."\n"; 输出: $`$& 而直接输出( ...

  9. 实战_4:UI开发工具-WindowBuilder

    介绍: WindowBuilder是谷歌开发的,开发java图形界面的工具,是一个eclipse插件. WindowBuilder支持开发多种形式的图形界面:SWT/JFace.Swing.GWT 安 ...

  10. 通过java语言实现MD5加密

    通过java语言实现MD5加密public static String getMd5(String str) { try { MessageDigest md5 = MessageDigest.get ...