题目链接:https://cn.vjudge.net/contest/283743#problem/C

题目大意:给你n个数组,然后问你是否有多个“相似”且不重叠的子串的长度大于等于5(两个子串相似当且仅当长度相等且每一位的数字差都相等)。

具体思路:对于相似,我们直接对于当前的输入的和他的上一位相减就可以了,这样差就表示出来了,然后就开始判断时候有相同的子串并且不重叠并且长度>=5就可以了。判断的时候,首先分组,分组的标准是这个组里面的height是不是大于等k,对于每一个组,找出最大的sa差值,然后就判断差值和5的关系就可以了。对于具体的原因,height[i]数组指的是排序之后,排名为i和i-1的最长公共前缀,然后再分组的时候,如果height数组>=k的时候,就直接判断这两个字符串的开头位置就可以了,这个可以通过sa数组实现。

AC代码:

 #include<iostream>
#include<stack>
#include<cstring>
#include<iomanip>
#include<stdio.h>
#include<algorithm>
#include<cmath>
using namespace std;
# define ll long long
# define inf 0x3f3f3f3f
const int maxn = 5e5+;
int cntA[maxn], cntB[maxn], sa[maxn], tsa[maxn], A[maxn], B[maxn], height[maxn];
int Rank[maxn];
int ch[maxn];
int sto[maxn];
ll n;
//sa[i]代表第i小的后缀位置,Rank[i]代表第i位置的后缀,排名第几小
// height[i]代表排名第i个字符串和第i-1个字符串的相同前缀有多少个
void cal()
{
for(int i = ; i < ; i++)
cntA[i] = ;
// cout<<1<<endl;
// cout<<n<<endl;
for(int i = ; i <= n; i++){
//cout<<ch[i-1]<<endl;
cntA[ch[i-]]++;
}
// cout<<1<<endl;
for(int i = ; i < ; i++)
cntA[i] += cntA[i-];
for(int i = n; i; i--)
sa[cntA[ch[i-]]--] = i;
Rank[sa[]] = ;
for(int i = ; i <= n; i++)
{
Rank[sa[i]] = Rank[sa[i-]];
if(ch[sa[i]-] != ch[sa[i-]-])
Rank[sa[i]]++;
}
for(int l = ; Rank[sa[n]] < n; l <<= )
{
memset(cntA, , sizeof(cntA));
memset(cntB, , sizeof(cntB));
for(int i = ; i <= n; i++)
{
cntA[A[i] = Rank[i]]++;
cntB[B[i] = (i+l <= n)?Rank[i+l]:]++;
}
for(int i = ; i <= n; i++)
cntB[i] += cntB[i-];
for(int i = n; i; i--)
tsa[cntB[B[i]]--] = i;
for(int i = ; i <= n; i++)
cntA[i] += cntA[i-];
for(int i = n; i; i--)
sa[cntA[A[tsa[i]]]--] = tsa[i];
Rank[sa[]]=;
for(int i = ; i <= n; i++)
{
Rank[sa[i]] = Rank[sa[i-]];
if(A[sa[i]] != A[sa[i-]] || B[sa[i]] != B[sa[i-]])
Rank[sa[i]]++;
}
}
for(int i = , j = ; i <= n; i++)
{
if(j)
j--;
while(ch[i+j-] == ch[sa[Rank[i]-] + j - ])
j++;
height[Rank[i]] = j;
}
}
bool judge(int t)
{
int mx=-inf,mm=inf;
for(int i=; i<=n; i++)
{
if(height[i]>=t)
{
mm=min(mm,min(sa[i],sa[i-]));
mx=max(mx,max(sa[i],sa[i-]));
if(mx-mm>t)
return true;
}
else
{
mm=inf;
mx=-inf;
}
}
return false;
}
int main()
{
// int n;
while(scanf("%d",&n)&&n)
{
for(int i=; i<n; i++)
{
scanf("%d",&sto[i]);
}
for(int i=; i<n; i++)
{
ch[i]=sto[i+]-sto[i]+;
}
n--;
cal();
int ans=-;
int l=,r=1e8;
while(l<=r)
{
int mid=(l+r)>>;
// cout<<l<<" "<<r<<endl;
if(judge(mid))
{
ans=mid;
l=mid+;
// cout<<ans<<endl;
}
else
{
r=mid-;
}
}
if(ans>=)
printf("%d\n",ans+);
else
{
printf("0\n");
}
}
return ;
}

C - Musical Theme (后缀数组)的更多相关文章

  1. POJ1743 Musical Theme [后缀数组]

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

  2. POJ 1743 Musical Theme 后缀数组 最长重复不相交子串

    Musical ThemeTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=1743 Description ...

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

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

  4. poj 1743 Musical Theme (后缀数组+二分法)

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 16162   Accepted: 5577 De ...

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

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

  6. Poj 1743 Musical Theme(后缀数组+二分答案)

    Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...

  7. [poj 1743] Musical Theme 后缀数组 or hash

    Musical Theme 题意 给出n个1-88组成的音符,让找出一个最长的连续子序列,满足以下条件: 长度大于5 不重叠的出现两次(这里的出现可以经过变调,即这个序列的每个数字全都加上一个整数x) ...

  8. Poj 1743 Musical Theme (后缀数组+二分)

    题目链接: Poj  1743 Musical Theme 题目描述: 给出一串数字(数字区间在[1,88]),要在这串数字中找出一个主题,满足: 1:主题长度大于等于5. 2:主题在文本串中重复出现 ...

  9. POJ 1743 Musical Theme ——后缀数组

    [题目分析] 其实找最长的不重叠字串是很容易的,后缀数组+二分可以在nlogn的时间内解决. 但是转调是个棘手的事情. 其实只需要o(* ̄▽ ̄*)ブ差分就可以了. 背板题. [代码] #include ...

  10. [Poj1743] [后缀数组论文例题] Musical Theme [后缀数组不可重叠最长重复子串]

    利用后缀数组,先对读入整数处理str[i]=str[i+1]-str[i]+90这样可以避免负数,计算Height数组,二分答案,如果某处H<lim则将H数组分开,最终分成若干块,判断每块中是否 ...

随机推荐

  1. 工作流管库的bpmn部署在数据库中

    工作流管库的bpmn部署在数据库中 DB_schema_update_false  没有表则创建 有表则报错 DB_SCHEMA_UPDATE_TRUE 没有表则创建 有表则不创建 脚本更新则更新数据 ...

  2. dfs和bfs(链式前向星实现)

    dfs代码: #include<iostream>#include<Algorithm>#include<cstring>#include<cstdio> ...

  3. 安卓创始人计划推出能帮你约会的AI手机

    安卓操作系统的创始人安迪·鲁宾早些年已经离开谷歌公司,离开谷歌后鲁宾成立Essential  Phone手机品牌.不过正如你所知道的那样尽管安迪·鲁宾有着很大的名气,但Essential  Phone ...

  4. Django的datetime.timedelta类(Django编程-2)

    datetime.timedelta对象代表两个时间之间的时间差,两个date或datetime对象相减就可以返回一个timedelta对象. 如果有人问你昨天是几号,这个很容易就回答出来了.但是如果 ...

  5. python+django+uwsgi 搭建环境

    第一步: 搭建python环境 最好使用  pyenv可以很好的管理多版本下的python环境 第二步:搭建django环境 使用    pip install django==1.12.1   来安 ...

  6. WinRM不起作用 Connecting to remote server failed with the following error message : WinRM cannot complete the operation

    当我运行下面的 powershell  脚本时: $FarmAcct = 'domain\user'  $secPassword = ConvertTo-SecureString 'aaa' -AsP ...

  7. 洛谷 P4475 巧克力王国 解题报告

    P4475 巧克力王国 题目描述 巧克力王国里的巧克力都是由牛奶和可可做成的.但是并不是每一块巧克力都受王国人民的欢迎,因为大家都不喜欢过于甜的巧克力. 对于每一块巧克力,我们设 \(x\) 和 \( ...

  8. 洛谷 P2491消防 解题报告

    P2491 消防 题目描述 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个 ...

  9. Java NIO -- 通道 Channel

    通道(Channel):由 java.nio.channels 包定义的.Channel 表示 IO 源与目标打开的连接.Channel 类似于传统的“流”.只不过 Channel本身不能直接访问数据 ...

  10. ASP.NET MVC 网站优化之压缩技术

    压缩 html 可以去除代码中无用的空格等,这样可提高网站的加载速度并节省带宽. 实现 ActionFilter 来完成 html 的压缩 public class WhitespaceFilterA ...