POJ1743:Musical Theme——题解
http://poj.org/problem?id=1743
给一段数,求最大相似子串长度,如果没有输出0。
相似子串定义:
1.两个不重叠的子串,其中一个是另一个加/减一个数得来的。
2.长度>=5
二分答案,然后想如何表示相似。
实际上我们对原数进行差分然后找相同不重叠子串即可,答案为长度+1。
但是我们考虑对于1 2 3这组数据答案为1(虽然你应该输出0),而用上面的方法会得到2,显然是不对的。
实际上上面差分得1 1 -3,1和1虽然为相同不重叠子串,但在原数组上他们是重叠的,所以我们规定两个子串之间必须差一个数。
具体的方法就是处理高度函数,找每个后缀的最长公共前缀即可。
细节:
处理高度函数和二分答案的时候要把末尾的数去掉。
数字不可为负,为此可以同时加上一个数。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
const int N=2e4+;
int n,rank[N],sa[N],height[N],w[N],s[N];
inline bool pan(int *x,int i,int j,int k){
int ti=i+k<n?x[i+k]:-;
int tj=j+k<n?x[j+k]:-;
return x[i]==x[j]&&ti==tj;
}
inline void SA_init(){
int *x=rank,*y=height,r=;
for(int i=;i<r;i++)w[i]=;
for(int i=;i<n;i++)w[s[i]]++;
for(int i=;i<r;i++)w[i]+=w[i-];
for(int i=n-;i>=;i--)sa[--w[s[i]]]=i;
r=;x[sa[]]=;
for(int i=;i<n;i++)
x[sa[i]]=s[sa[i]]==s[sa[i-]]?r-:r++;
for(int k=;r<n;k<<=){
int yn=;
for(int i=n-k;i<n;i++)y[yn++]=i;
for(int i=;i<n;i++)
if(sa[i]>=k)y[yn++]=sa[i]-k;
for(int i=;i<r;i++)w[i]=;
for(int i=;i<n;i++)++w[x[y[i]]];
for(int i=;i<r;i++)w[i]+=w[i-];
for(int i=n-;i>=;i--)sa[--w[x[y[i]]]]=y[i];
swap(x,y);r=;x[sa[]]=;
for(int i=;i<n;i++)
x[sa[i]]=pan(y,sa[i],sa[i-],k)?r-:r++;
}
for(int i=;i<n;i++)rank[i]=x[i];
}
inline void height_init(){
int i,j,k=;
for(i=;i<=n;i++)rank[sa[i]]=i;
for(i=;i<n;i++){
if(k)k--;
else k=;
j=sa[rank[i]-];
while(s[i+k]==s[j+k])k++;
height[rank[i]]=k;
}
}
bool check(int k){
int maxn,minn;
maxn=minn=sa[];
for(int i=;i<=n;i++){
if(height[i]>=k&&i<n){
minn=min(minn,sa[i]);
maxn=max(maxn,sa[i]);
continue;
}
if(maxn-minn>=k)return ;
maxn=minn=sa[i];
}
return ;
}
int erfen(int l,int r){
while(l<r){
int mid=(l+r+)>>;
if(check(mid))l=mid;
else r=mid-;
}
if(l<)return ;
return l+;
}
int main(){
while(scanf("%d",&n)!=EOF&&n){
for(int i=;i<n;i++)scanf("%d",&s[i]);
for(int i=;i<n-;i++)s[i]=s[i+]-s[i]+;
s[n-]=;
SA_init();
n--;
height_init();
printf("%d\n",erfen(,n));
}
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
POJ1743:Musical Theme——题解的更多相关文章
- POJ1743 Musical Theme —— 后缀数组 重复出现且不重叠的最长子串
题目链接:https://vjudge.net/problem/POJ-1743 Musical Theme Time Limit: 1000MS Memory Limit: 30000K Tot ...
- POJ1743 Musical Theme [后缀数组]
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ...
- POJ1743 Musical Theme [后缀数组+分组/并查集]
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ...
- poj1743 Musical Theme【后缀数组】【二分】
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 35044 Accepted: 11628 D ...
- POJ-1743 Musical Theme,后缀数组+二分!
Musical Theme 人生第一道后缀数组的题,采用大众化思想姿势极其猥琐. 题意:给你n个 ...
- POJ1743 Musical Theme
Description A musical melody is represented as a sequence of N (1<=N<=20000)notes that are int ...
- POJ1743 Musical Theme (后缀数组 & 后缀自动机)最大不重叠相似子串
A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the ...
- POJ1743 Musical Theme(后缀数组 二分)
Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 33462 Accepted: 11124 Description A m ...
- POJ-1743 Musical Theme(最长不可重叠子串,后缀数组+二分)
A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the ...
随机推荐
- Linux tcpdump命令详解(分享文章)
简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具. tcpdump可以将网络中传送的数据包的 ...
- android学习十三 首选项
1,首选项可用用来持久保存用户设置,游戏最高分等 2,首选项有,列表首选项,复选框首选项,对话框首选项.. 3,通过xml文件和代码创建首选项 addPreferencesFromResou ...
- Ruby 基础教程1-9
异常 1.异常结构 [ begin] ... rescue [retry] ... [ensure] . ...
- hdu1257最少拦截系统(暴力)
最少拦截系统 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- Linux命令应用大词典-第41章 MySQL数据库
41.1 mysqld_safe:MySQL服务器启动脚本 41.2 mysql_install_db:初始化MySQL数据目录 41.3 mysqlshow:显示MySQL数据库结构 41.4 my ...
- 【icon】 图标组件说明
小程序默认了几种类型图标,其组件原型如下: <icon type="[success | success_no_circle | info | warn | waiting | can ...
- 【WXS】变量定义保留标识符
以下字符不能作为变量名称定义: delete void typeof null undefined NaN Infinity var if else true false require this f ...
- JavaScript 数组操作方法 和 ES5数组拓展
JavaScript中数组有各种操作方法,以下通过举例来说明各种方法的使用: 数组操作方法 push 在数组最后添加一个元素 var arr=[3,4,5,6] console.log(arr) // ...
- 并发HashMap的put操作引起死循环
今天研读Java并发容器和框架时,看到为什么要使用ConcurrentHashMap时,其中有一个原因是:线程不安全的HashMap, HashMap在并发执行put操作时会引起死循环,是因为多线程会 ...
- POJ 2184 Cow Exhabition
"Fat and docile, big and dumb, they look so stupid, they aren't much fun..." - Cows with G ...