http://poj.org/problem?id=1743

给一段数,求最大相似子串长度,如果没有输出0。

相似子串定义:

1.两个不重叠的子串,其中一个是另一个加/减一个数得来的。

2.长度>=5

二分答案,然后想如何表示相似。

实际上我们对原数进行差分然后找相同不重叠子串即可,答案为长度+1。

但是我们考虑对于1 2 3这组数据答案为1(虽然你应该输出0),而用上面的方法会得到2,显然是不对的。

实际上上面差分得1 1 -3,1和1虽然为相同不重叠子串,但在原数组上他们是重叠的,所以我们规定两个子串之间必须差一个数。

具体的方法就是处理高度函数,找每个后缀的最长公共前缀即可。

细节:

处理高度函数和二分答案的时候要把末尾的数去掉。

数字不可为负,为此可以同时加上一个数。

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cctype>
  5. #include<cstdio>
  6. #include<vector>
  7. #include<queue>
  8. #include<cmath>
  9. using namespace std;
  10. const int N=2e4+;
  11. int n,rank[N],sa[N],height[N],w[N],s[N];
  12. inline bool pan(int *x,int i,int j,int k){
  13. int ti=i+k<n?x[i+k]:-;
  14. int tj=j+k<n?x[j+k]:-;
  15. return x[i]==x[j]&&ti==tj;
  16. }
  17. inline void SA_init(){
  18. int *x=rank,*y=height,r=;
  19. for(int i=;i<r;i++)w[i]=;
  20. for(int i=;i<n;i++)w[s[i]]++;
  21. for(int i=;i<r;i++)w[i]+=w[i-];
  22. for(int i=n-;i>=;i--)sa[--w[s[i]]]=i;
  23. r=;x[sa[]]=;
  24. for(int i=;i<n;i++)
  25. x[sa[i]]=s[sa[i]]==s[sa[i-]]?r-:r++;
  26. for(int k=;r<n;k<<=){
  27. int yn=;
  28. for(int i=n-k;i<n;i++)y[yn++]=i;
  29. for(int i=;i<n;i++)
  30. if(sa[i]>=k)y[yn++]=sa[i]-k;
  31. for(int i=;i<r;i++)w[i]=;
  32. for(int i=;i<n;i++)++w[x[y[i]]];
  33. for(int i=;i<r;i++)w[i]+=w[i-];
  34. for(int i=n-;i>=;i--)sa[--w[x[y[i]]]]=y[i];
  35. swap(x,y);r=;x[sa[]]=;
  36. for(int i=;i<n;i++)
  37. x[sa[i]]=pan(y,sa[i],sa[i-],k)?r-:r++;
  38. }
  39. for(int i=;i<n;i++)rank[i]=x[i];
  40. }
  41. inline void height_init(){
  42. int i,j,k=;
  43. for(i=;i<=n;i++)rank[sa[i]]=i;
  44. for(i=;i<n;i++){
  45. if(k)k--;
  46. else k=;
  47. j=sa[rank[i]-];
  48. while(s[i+k]==s[j+k])k++;
  49. height[rank[i]]=k;
  50. }
  51. }
  52. bool check(int k){
  53. int maxn,minn;
  54. maxn=minn=sa[];
  55. for(int i=;i<=n;i++){
  56. if(height[i]>=k&&i<n){
  57. minn=min(minn,sa[i]);
  58. maxn=max(maxn,sa[i]);
  59. continue;
  60. }
  61. if(maxn-minn>=k)return ;
  62. maxn=minn=sa[i];
  63. }
  64. return ;
  65. }
  66. int erfen(int l,int r){
  67. while(l<r){
  68. int mid=(l+r+)>>;
  69. if(check(mid))l=mid;
  70. else r=mid-;
  71. }
  72. if(l<)return ;
  73. return l+;
  74. }
  75. int main(){
  76. while(scanf("%d",&n)!=EOF&&n){
  77. for(int i=;i<n;i++)scanf("%d",&s[i]);
  78. for(int i=;i<n-;i++)s[i]=s[i+]-s[i]+;
  79. s[n-]=;
  80. SA_init();
  81. n--;
  82. height_init();
  83. printf("%d\n",erfen(,n));
  84. }
  85. return ;
  86. }

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

POJ1743:Musical Theme——题解的更多相关文章

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

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

  2. POJ1743 Musical Theme [后缀数组]

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

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

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

  4. poj1743 Musical Theme【后缀数组】【二分】

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 35044   Accepted: 11628 D ...

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

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

  6. POJ1743 Musical Theme

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

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

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

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

    Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 33462   Accepted: 11124 Description A m ...

  9. POJ-1743 Musical Theme(最长不可重叠子串,后缀数组+二分)

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

随机推荐

  1. 数据库路由中间件MyCat - 背景篇(2)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. MyCat的前世今生 如前文所说,Amoeba.Cobar.MyCat等属于同宗一脉.若Amoeba能继续下 ...

  2. 基于Docker的UI自动化初探

    本文来自网易云社区 前言 一直以来,项目迭代的时间都是比较紧张的,开发加班加点coding,测试加班加点提bug.都说"时间像海绵里的水,挤挤总会有的"(当然这里的"挤挤 ...

  3. 一个只有十行的精简MVVM框架(上篇)

    本文来自网易云社区. 前言 MVVM模式相信做前端的人都不陌生,去网上搜MVVM,会出现一大堆关于MVVM模式的博文,但是这些博文大多都只是用图片和文字来进行抽象的概念讲解,对于刚接触MVVM模式的新 ...

  4. linux部署MantisBT(二)部署php

    二.部署php 1.下载php安装包 http://php.net/downloads.php 2.安装php yum install libxml2 yum install libxml2-deve ...

  5. MATLAB实现连续周期信号的频谱分析(正余弦波信号举例)

    关于MATLAB实现连续信号的频谱分析,以正余弦波信号频谱分析为例分析如下: 1.含有频率f ,2f和3f的正弦波叠加信号,即: 其中,f =500Hz.试采用Matlab仿真软件对该信号进行频谱分析 ...

  6. Unity编辑器 - 输入控件聚焦问题

    Unity编辑器整理 - 输入控件聚焦问题 EditorGUI的输入控件在聚焦后,如果在其他地方改变值,聚焦的框不会更新,而且无法取消聚焦,如下图: 在代码中取消控件的聚焦 取消聚焦的"时机 ...

  7. ubuntu 执行Python脚本出现: /usr/bin/env: ‘python\r’: No such file or directory

    原因: #!/usr/bin/env python 在ubuntu会变成 #!/usr/bin/env python\r 而\r 会被shell 当成参数 所以出现:  /usr/bin/env: ‘ ...

  8. 凸包算法(Graham扫描法)详解

    先说下基础知识,不然不好理解后面的东西 两向量的X乘p1(x1,y1),p2(x2,y2) p1Xp2如果小于零则说明  p1在p2的逆时针方向 如果大于零则说明 p1在p2的顺时针方向 struct ...

  9. Spark- 根据IP获取城市(java)

    开源 IP 地址定位库 ip2region 1.4 ip2region 是准确率 99.9% 的 IP 地址定位库,0.0x毫秒级查询,数据库文件大小只有 2.7M,提供了 Java.PHP.C.Py ...

  10. Spark mlib的本地向量

    Spark mlib的本地向量有两种: DenseVctor :稠密向量 其创建方式 Vector.dense(数据) SparseVector :稀疏向量 其创建方式有两种: 方法一:Vector. ...