题目大意:给一个整数序列,找出最长的连续变化相同的、至少出现两次并且不相重叠一个子序列。

题目分析:二分枚举长度进行判定。

代码如下:

  1. # include<iostream>
  2. # include<cstdio>
  3. # include<cstring>
  4. # include<algorithm>
  5. using namespace std;
  6. # define mid (l+(r-l)/2)
  7.  
  8. const int N=20000;
  9.  
  10. int SA[N+5],height[N+5];
  11. int *rk,*tSA;
  12. int n,a[N+5],cnt[N+5];
  13.  
  14. bool same(int i,int j,int k)
  15. {
  16. if(tSA[i]!=tSA[j]) return false;
  17. if(i+k>=n&&j+k>=n) return true;
  18. if(i+k>=n&&j+k<n) return false;
  19. if(i+k<n&&j+k>=n) return false;
  20. return tSA[i+k]==tSA[j+k];
  21. }
  22.  
  23. void buildSA()
  24. {
  25. int m=180;
  26. for(int i=0;i<m;++i) cnt[i]=0;
  27. for(int i=0;i<n;++i) ++cnt[rk[i]=a[i]];
  28. for(int i=1;i<m;++i) cnt[i]+=cnt[i-1];
  29. for(int i=n-1;i>=0;--i) SA[--cnt[rk[i]]]=i;
  30.  
  31. for(int k=1;k<n;k<<=1){
  32. int p=0;
  33. for(int i=n-k;i<n;++i) tSA[p++]=i;
  34. for(int i=0;i<n;++i) if(SA[i]>=k) tSA[p++]=SA[i]-k;
  35.  
  36. for(int i=0;i<m;++i) cnt[i]=0;
  37. for(int i=0;i<n;++i) ++cnt[rk[tSA[i]]];
  38. for(int i=1;i<m;++i) cnt[i]+=cnt[i-1];
  39. for(int i=n-1;i>=0;--i) SA[--cnt[rk[tSA[i]]]]=tSA[i];
  40.  
  41. swap(rk,tSA);
  42. p=1;
  43. rk[SA[0]]=0;
  44. for(int i=1;i<n;++i){
  45. if(same(SA[i],SA[i-1],k)) rk[SA[i]]=p-1;
  46. else rk[SA[i]]=p++;
  47. }
  48. if(p>=n) break;
  49. m=p;
  50. }
  51. }
  52.  
  53. void getHeight()
  54. {
  55. for(int i=0;i<n;++i) rk[SA[i]]=i;
  56. int k=0;
  57. height[0]=0;
  58. for(int i=0;i<n;++i){
  59. if(rk[i]==0) k=0;
  60. else{
  61. if(k) --k;
  62. int j=SA[rk[i]-1];
  63. while(i+k<n&&j+k<n&&a[i+k]==a[j+k]) ++k;
  64. height[rk[i]]=k;
  65. }
  66. }
  67. }
  68.  
  69. bool ok(int x)
  70. {
  71. int maxn=SA[0],minn=SA[0];
  72. for(int i=1;i<n;++i){
  73. if(minn+x<maxn) return true;
  74. if(height[i]>=x){
  75. maxn=max(maxn,SA[i]);
  76. minn=min(minn,SA[i]);
  77. }else{
  78. maxn=minn=SA[i];
  79. }
  80. }
  81. return minn+x<maxn;
  82. }
  83.  
  84. void init()
  85. {
  86. rk=new int[n+5];
  87. tSA=new int[n+5];
  88. }
  89.  
  90. void destroy()
  91. {
  92. delete []rk;
  93. delete []tSA;
  94. }
  95.  
  96. int main()
  97. {
  98. while(scanf("%d",&n)&&n)
  99. {
  100. init();
  101. for(int i=0;i<n;++i){
  102. scanf("%d",a+i);
  103. --a[i];
  104. }
  105. --n;
  106. int temp=a[0];
  107. for(int i=0;i<n;++i){
  108. a[i]=a[i+1]-temp+87;
  109. temp=a[i+1];
  110. }
  111.  
  112. buildSA();
  113. getHeight();
  114.  
  115. //二分枚举最短的不满足条件的
  116. int l=4,r=n;
  117. while(l<r){
  118. if(ok(mid)) l=mid+1;
  119. else r=mid;
  120. }
  121. printf("%d\n",l>=5?l:0);
  122. destroy();
  123. }
  124. return 0;
  125. }

  

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

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

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

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

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

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

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

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

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

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

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

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

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

  7. POJ 1743 Musical Theme ( 后缀数组 && 最长不重叠相似子串 )

    题意 : 给 n 个数组成的串,求是否有多个“相似”且不重叠的子串的长度大于等于5,两个子串相似当且仅当长度相等且每一位的数字差都相等. 分析 :  根据题目对于 “ 相似 ” 串的定义,我们可以将原 ...

  8. POJ.1743.Musical Theme(后缀数组 倍增 二分 / 后缀自动机)

    题目链接 \(Description\) 给定一段数字序列(Ai∈[1,88]),求最长的两个子序列满足: 1.长度至少为5 2.一个子序列可以通过全部加或减同一个数来变成另一个子序列 3.两个子序列 ...

  9. POJ 1743 Musical Theme 后缀数组 不可重叠最长反复子串

    二分长度k 长度大于等于k的分成一组 每组sa最大的和最小的距离大于k 说明可行 #include <cstdio> #include <cstring> #include & ...

  10. poj 1743 Musical Theme 后缀自动机/后缀数组/后缀树

    题目大意 直接用了hzwer的题意 题意:有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的主题."主题&qu ...

随机推荐

  1. iOS - OC NSStream 文件流

    前言 @interface NSStream : NSObject @interface NSOutputStream : NSStream 1.文件流的使用 NSString *filePath = ...

  2. Java开发高薪之路__大纲篇

    本人小白,现对java开发做出以下总结,内容将从初级开始,逐步完善与摸索. 基础篇 网页篇 Android篇 高级建设篇 数据篇 系统篇

  3. Http协议总结

    Http协议(Hyper Text Transfer Protocol)是目前网络上使用最广泛的,面向应用层的协议.它基于传输层的TCP协议进行通信.它是一种通用的,无状态的协议(不对当前的状态进行记 ...

  4. APP成功上线前的bug解决方案

    首先测试用例设计阶段,设计并维护一个各个功能入口的说明文档.其实这个文档的作用很大,一方面对于bug回归阶段的人来说,这是用于提醒的;另外一个方面,在随机测试的时候,随机程度也能有所提高,测试人员能够 ...

  5. reg.test is not a function 报错

    正则中 比如 var reg = "/^[0-9]$/" 会报 reg.test is not a function 如果 var reg = /^[0-9]$/ 就不会有错 因为 ...

  6. EaseType缓动函数

    http://sol.gfxile.net/interpolation/   一篇很详细的图文

  7. 【CSS3】标签使用说明

    转换(transform):改变元素的形状.大小和位置. transform:rotate(20deg):顺时针旋转20° rotate()用来2D旋转改变角度.支持负数,表示逆时针. transfo ...

  8. 动态规划(一)——最长公共子序列和最长公共子串

    注: 最长公共子序列采用动态规划解决,由于子问题重叠,故采用数组缓存结果,保存最佳取值方向.输出结果时,则自顶向下建立二叉树,自底向上输出,则这过程中没有分叉路,结果唯一. 最长公共子串采用参考串方式 ...

  9. 读javascript高级程序设计01-基本概念、数据类型、函数

    一. javascript构成 1.javascript实现由三部分组成: ECMAScript:核心语言功能 DOM:文档对象模型,提供访问和操作网页内容的方法和接口 BOM:浏览器对象模型,提供与 ...

  10. DbUtils常用API的使用 方便以后查阅

    package com.lizhou.Test; import java.sql.SQLException; import java.util.List; import java.util.Map; ...