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

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. updatepanel局部刷新功能,实现注册时对用户名的检测

    updatepanel的使用 通过将控件放入到updatepanel中,实现局部刷新. 前台代码:<asp:ScriptManager ID="ScriptManager1" ...

  2. SQL server 如何附加、还原、分离、备份数据库文件

    No1 : 附加 No2 : 还原            一.(需要 .bak文件)首先建立一个数据库,数据库名称与你的.bak文件名要相同. 当然.这时候的这个数据库还是空的,需要还原回去数据.右键 ...

  3. 02.[WPF]如何固定窗口的大小

    在WPF开发过程中碰到一个需求,要求保证窗口大小不变,即便是双击 titlebar 也不能改变窗口大小和位置.要实现这样的效果,需要执行如下步骤: 1,分别设置窗口的 Width/MaxWidth/M ...

  4. 查找被锁对象的名称、sid,锁定的类型-1123

    select lk.sid,lk_obj.object_id,obj.object_name,DECODE(LK.LMODE,0,'None',1,'Null',2,'Row-S (SS)',3,'R ...

  5. OC - 29.自定义布局实现瀑布流

    概述 瀑布流是电商应用展示商品通常采用的一种方式,如图示例 瀑布流的实现方式,通常有以下几种 通过UITableView实现(不常用) 通过UIScrollView实现(工作量较大) 通过UIColl ...

  6. HttpClient的get+post请求使用

    啥都不说,先上代码 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReade ...

  7. C# 线程间互相通信

    C#线程间互相通信主要用到两个类:AutoResetEvent和ManualResetEvent. 一.AutoResetEvent AutoResetEvent 允许线程通过发信号互相通信,线程通过 ...

  8. Shell脚本——DHCP自动部署

    详细说明参考: (三)跟我一起玩Linux网络服务:DHCP服务配置之主服务器配置 #! /bin/bash IPSAG="10.10.10" DNSIP="10.10. ...

  9. input file文件上传样式

    <style>    .file-group {        position: relative;        width: 200px;        height: 80px;  ...

  10. Dynamic Web Module 3.0 requires Java 1.6 or newer报错

    在项目的pom.xml的<build></build>标签中加入: <plugins> <plugin> <groupId>org.apac ...