【题目链接】
 
  
 
 
【题意】
 
 
  求不可重叠最长重复子串。
 

2015-11-27

【思路】

  1)      据题意处理字符串

  2)      后缀数组。二分长度k,问题成为了判定是否存在两个及以上长度不小于k且互不重叠的子串。根据height数组划分后缀,满足两个条件:一是一组内height值不小于k(保证组内任两个长度不小于k即存在长度不小于k的子串),二是组内后缀sa值的最大最小值之差大于等于k(保证两个子串不重叠)。

  需要注意n==1时需要特判。

  1/为什么可以划分height数组呢?首先height[i]代表lcp(suffix(sa[i]),suffix(sa[i-1])),所以height所对应的后缀是有序的,如果划分出现height<k的话以后的后缀与改组内的lcp一定不大于k-1,所以不会出现后面的再划分到改组的情况。

【代码】

 #include<cstdio>
#include<cstring>
#include<iostream>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; const int maxn = +; int s[maxn];
int sa[maxn],t[maxn],t2[maxn],c[maxn],n; void build_sa(int m) {
int i,*x=t,*y=t2;
for(int i=;i<m;i++) c[i]=;
for(int i=;i<n;i++) c[x[i]=s[i]]++;
for(int i=;i<m;i++) c[i]+=c[i-];
for(int i=n-;i>=;i--) sa[--c[x[i]]]=i; for(int k=;k<=n;k<<=) {
int p=;
for(int i=n-k;i<n;i++) y[p++]=i;
for(int i=;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k; for(int i=;i<m;i++) c[i]=;
for(int i=;i<n;i++) c[x[y[i]]]++;
for(int i=;i<m;i++) c[i]+=c[i-];
for(int i=n-;i>=;i--) sa[--c[x[y[i]]]]=y[i]; swap(x,y);
p=; x[sa[]]=;
for(int i=;i<n;i++)
x[sa[i]]=y[sa[i-]]==y[sa[i]] && y[sa[i-]+k]==y[sa[i]+k]?p-:p++;
if(p>=n) break;
m=p;
}
} int rank[maxn],height[maxn];
void getHeight() {
int i,j,k=;
for(int i=;i<n;i++) rank[sa[i]]=i;
for(int i=;i<n;i++) {
if(k) k--;
int j=sa[rank[i]-];
while(s[i+k]==s[j+k]) k++;
height[rank[i]]=k;
}
} bool can(int k) {
int min=sa[],max=sa[];
for(int i=;i<n;i++) {
if(height[i]<k) min=max=sa[i];
if(sa[i]<min) min=sa[i];
if(sa[i]>max) max=sa[i];
if(max-min>=k) return true;
}
return false;
} int main() {
while(scanf("%d",&n)== && n)
{
for(int i=;i<n;i++)scanf("%d",&s[i]);
for(int i=n-;i>;i--)s[i]=s[i]-s[i-]+;
n--;
for(int i=;i<n;i++)s[i]=s[i+];
s[n]=;
build_sa();
getHeight();
int L=,R=n/;
while(L<R) {
int M=L+(R-L+)/;
if(can(M)) L=M; else R=M-;
}
L++;
if(L<=) printf("0\n");
else printf("%d\n",L);
}
return ;
}

2016-2-19

【思路】

  

  SAM+DP

  处理出right集的最大值mx和最小值mn,即该状态对应所有字符串的结束位置的最大与最小,递推式为:

    mx[p]=max{ l[p], mx[np],np->fa=p }

    mn[p]=min{ l[p], mn[np],np->fa=p }

  则状态i对应字符串中的最长重复子串的长度为min{l[i],mx[i]-mn[i]},可以拿个栗子自己看一下,这样保证了不重叠。然后取所有状态的最大值即可。

【代码】

 #include<cstdio>
#include<cstring>
#include<iostream>
using namespace std; const int N = *1e4+;
const int sigma = ; int s[N/];
int root,last,sz,ch[N][sigma],fa[N],l[N],mn[N],mx[N];
int b[N],cnt[N],n; void init() {
sz=; root=last=++sz;
memset(fa,,sizeof(fa));
memset(mx,,sizeof(mx));
memset(mn,,sizeof(mn));
memset(cnt,,sizeof(cnt));
memset(ch,,sizeof(ch));
}
void add(int x) {
int c=s[x];
int p=last,np=++sz; last=np;
mn[np]=mx[np]=l[np]=x;
for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
if(!p) fa[np]=root;
else {
int q=ch[p][c];
if(l[p]+==l[q]) fa[np]=q;
else {
int nq=++sz; l[nq]=l[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];
fa[np]=fa[q]=nq;
for(;p&&q==ch[p][c];p=fa[p]) ch[p][c]=nq;
}
}
}
void solve() {
for(int i=;i<=sz;i++) cnt[l[i]]++;
for(int i=;i<=n;i++) cnt[i]+=cnt[i-];
for(int i=;i<=sz;i++) b[cnt[l[i]]--]=i;
int ans=;
for(int i=sz;i;i--) {
int p=b[i];
if(fa[p]) {
if(mn[fa[p]]>mn[p]) mn[fa[p]]=mn[p];
if(mx[fa[p]]<mx[p]) mx[fa[p]]=mx[p];
}
}
for(int i=;i<=sz;i++)
ans=max(ans,min(l[i],mx[i]-mn[i]));
if(ans<) puts("");
else printf("%d\n",ans+);
}
void read(int& x) {
char c=getchar(); int f=; x=;
while(!isdigit(c)){if(c=='-')f=-;c=getchar();}
while(isdigit(c)) x=x*+c-'',c=getchar();
x*=f;
} int main() {
while(read(n),n) {
init();
for(int i=;i<=n;i++) read(s[i]); n--;
for(int i=;i<=n;i++) s[i]=s[i+]-s[i]+,add(i);
solve();
}
return ;
}

poj1743 Musical Theme(后缀数组|后缀自动机)的更多相关文章

  1. POJ1743 Musical Theme(二分+后缀数组)

    题目大概是给n个数组成的串,求是否有多个“相似”且不重叠的子串的长度大于等于5,两个子串相似当且仅当长度相等且每一位的数字差都相等. 这题是传说中楼教主男人八题之一,虽然已经是用后缀数组解决不可重叠最 ...

  2. POJ1743 Musical Theme —— 后缀数组 重复出现且不重叠的最长子串

    题目链接:https://vjudge.net/problem/POJ-1743 Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Tot ...

  3. 字符串的模板 Manacher kmp ac自动机 后缀数组 后缀自动机

    为何scanf("%s", str)不需要&运算 经常忘掉的字符串知识点,最好不加&,不加&最标准,指针如果像scanf里一样加&是错的,大概是未定 ...

  4. 【整理】如何选取后缀数组&&后缀自动机

    后缀家族已知成员         后缀树         后缀数组         后缀自动机         后缀仙人掌         后缀预言         后缀Splay ? 后缀树是后缀数 ...

  5. loj6173 Samjia和矩阵(后缀数组/后缀自动机)

    题目: https://loj.ac/problem/6173 分析: 考虑枚举宽度w,然后把宽度压位集中,将它们哈希 (这是w=2的时候) 然后可以写一下string=“ac#bc” 然后就是求这个 ...

  6. POJ1743 Musical Theme (后缀数组 & 后缀自动机)最大不重叠相似子串

    A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the ...

  7. POJ1743 Musical Theme [后缀数组]

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 27539   Accepted: 9290 De ...

  8. POJ1743 Musical Theme [后缀数组+分组/并查集]

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 27539   Accepted: 9290 De ...

  9. POJ-1743 Musical Theme,后缀数组+二分!

                                                        Musical Theme 人生第一道后缀数组的题,采用大众化思想姿势极其猥琐. 题意:给你n个 ...

随机推荐

  1. (转)smarty实现多级分类的方法

    --http://www.aspku.com/kaifa/php/44679.html 这篇文章主要介绍了smarty实现多级分类的方法,涉及循环读取的技巧,非常具有实用价值,需要的朋友可以参考下   ...

  2. Android layout的横竖屏处理

    一.layout-land和layout-prot的区别与使用 默认情况下,创建的Android项目里只有一个layout文件夹,尽管这样也可以横竖屏切换用,但是某些布局横屏过后闲的格外的丑,如下图 ...

  3. SQL SERVER 中PatIndex的用法个人理解

    一般用法:PatIndex('%AAA%',‘BBBBBBBB’) 上句的意思是查找AAA在BBBBBBBB中的位置,从1开始计算,如果没有的话则返回0 其中%AAA%的用法和 SQL语句中like的 ...

  4. SGU 171.Sarov zones

    简单的贪心.优先weight最大的,优先匹配Q值大的地区 code #include <iostream> #include <algorithm> #include < ...

  5. 『重构--改善既有代码的设计』读书笔记----Hide Delegate

    所谓委托关系,就是一个类对于另一个类来说纯粹作为接口转发,即客户通过一个委托类去调用另一个对象.直白的委托关系就是委托类直接返回出目标类给客户调用,这个关系很麻烦,因为委托关系的变动就会影响客户端的代 ...

  6. Android ListView+image的使用

    首先创建layout部局文件xml: <?xml version="1.0" encoding="utf-8"?> <RelativeLayo ...

  7. 五分钟看懂js关键字this

    this是js里面很常用的关键字,而灵活的js也赋予了这个关键字无穷的生命力,相信你也有被它糊弄的时候,我总结了一个6字原则,大部分场合都能清醒分辨this到底指向who,跟大家分享一下,欢迎指正. ...

  8. C#中foreach遍历学习笔记

    using System; using System.Collections; using System.Collections.Generic; using System.Linq; using S ...

  9. 响应式十日谈第一日:使用 rem 设置文字大小

    上面回顾: 在序言中我们已经提到了响应式的一些基本理念,比如: 响应式网页不仅仅是响应不同类型的设备,而且需要响应不同的用户需求.响应式的初衷是为了让信息更好的传递交流,让所有人无障碍的获取信息,同时 ...

  10. Android中AppWidget的分析与应用:AppWidgetProvider .

    from: http://blog.csdn.net/thl789/article/details/7887968 本文从开发AppWidgetProvider角度出发,看一个AppWidgetPrv ...