题意:求一个字符串的不重叠最长相同变化的子串

n<=20000

思路:这是一道论文题

我们将原串两两之间作差,可以发现所求的相同变化的子串作出的差相同

问题就转化成了不重叠的最长重复子串

显然答案有二分性,二分答案,将问题转化为是否存在长度为k的相同子串

将后缀分成连续的若干组,每组相邻的height都不小于k

有希望满足条件的两个后缀一定在同一组

只要判断某组中的sa最大与最小值之差是否不小于k即可

有一组满足则k满足

  1. var a,b,wc,wd,x,y,height,sa,rank:array[..]of longint;
  2. n,i,l,r,mid,last,m:longint;
  3.  
  4. function cmp(a,b,l:longint):boolean;
  5. begin
  6. exit((y[a]=y[b])and(y[a+l]=y[b+l]));
  7. end;
  8.  
  9. procedure swap(var x,y:longint);
  10. var t:longint;
  11. begin
  12. t:=x; x:=y; y:=t;
  13. end;
  14.  
  15. procedure getsa(n:longint);
  16. var i,j,p:longint;
  17. begin
  18. for i:= to n- do
  19. begin
  20. x[i]:=a[i];
  21. inc(wc[a[i]]);
  22. end;
  23. for i:= to m do wc[i]:=wc[i-]+wc[i];
  24. for i:=n- downto do
  25. begin
  26. dec(wc[x[i]]);
  27. sa[wc[x[i]]]:=i;
  28. end;
  29. j:=; p:=;
  30. while p<n do
  31. begin
  32. p:=;
  33. for i:=n-j to n- do
  34. begin
  35. y[p]:=i; inc(p);
  36. end;
  37. for i:= to n- do
  38. if sa[i]>=j then begin y[p]:=sa[i]-j; inc(p); end;
  39. for i:= to n- do wd[i]:=x[y[i]];
  40. for i:= to m do wc[i]:=;
  41. for i:= to n- do inc(wc[wd[i]]);
  42. for i:= to m do wc[i]:=wc[i-]+wc[i];
  43. for i:=n- downto do
  44. begin
  45. dec(wc[wd[i]]);
  46. sa[wc[wd[i]]]:=y[i];
  47. end;
  48. for i:= to n do swap(x[i],y[i]);
  49. p:=; x[sa[]]:=;
  50. for i:= to n- do
  51. begin
  52. if cmp(sa[i-],sa[i],j) then x[sa[i]]:=p-
  53. else begin x[sa[i]]:=p; inc(p); end;
  54. end;
  55. j:=j*;
  56. m:=p;
  57. end;
  58. end;
  59.  
  60. procedure getheight(n:longint);
  61. var i,j,k:longint;
  62. begin
  63. k:=;
  64. for i:= to n do rank[sa[i]]:=i;
  65. for i:= to n- do
  66. begin
  67. if k> then dec(k);
  68. j:=sa[rank[i]-];
  69. while a[i+k]=a[j+k] do inc(k);
  70. height[rank[i]]:=k;
  71. end;
  72. end;
  73.  
  74. function min(x,y:longint):longint;
  75. begin
  76. if x<y then exit(x);
  77. exit(y);
  78. end;
  79.  
  80. function max(x,y:longint):longint;
  81. begin
  82. if x>y then exit(x);
  83. exit(y);
  84. end;
  85.  
  86. function isok(x:longint):boolean;
  87. var l,r,i:longint;
  88. begin
  89. l:=sa[]; r:=sa[];
  90. for i:= to n- do
  91. if height[i]<x then
  92. begin
  93. l:=sa[i]; r:=sa[i];
  94. end
  95. else
  96. begin
  97. l:=min(l,sa[i]);
  98. r:=max(r,sa[i]);
  99. if r-l>=x then exit(true);
  100. end;
  101. exit(false);
  102. end;
  103.  
  104. begin
  105. assign(input,'poj1743.in'); reset(input);
  106. assign(output,'poj1743.out'); rewrite(output);
  107. while not eof do
  108. begin
  109. fillchar(a,sizeof(a),);
  110. fillchar(b,sizeof(b),);
  111. fillchar(sa,sizeof(sa),);
  112. fillchar(rank,sizeof(rank),);
  113. fillchar(x,sizeof(x),);
  114. fillchar(y,sizeof(y),);
  115. fillchar(height,sizeof(height),);
  116. fillchar(wc,sizeof(wc),);
  117. fillchar(wd,sizeof(wd),);
  118. readln(n);
  119. if n= then break;
  120. for i:= to n- do read(b[i]);
  121. dec(n);
  122. for i:= to n- do a[i]:=b[i+]-b[i]+;
  123. a[n]:=; m:=;
  124. getsa(n+);
  125. getheight(n);
  126. l:=; r:=(n-) div ; last:=;
  127. while l<=r do
  128. begin
  129. mid:=(l+r)>>;
  130. if isok(mid) then begin last:=mid; l:=mid+; end
  131. else r:=mid-;
  132. end;
  133. if last< then writeln()
  134. else writeln(last+);
  135. // for i:= to n do write(sa[i]+,' ');
  136. // writeln;
  137. // for i:= to n do writeln(height[i]);
  138.  
  139. end;
  140.  
  141. close(input);
  142. close(output);
  143. end.

【POJ1743】Musical Theme(后缀数组,二分)的更多相关文章

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

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

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

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

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

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

  4. POJ 1743 [USACO5.1] Musical Theme (后缀数组+二分)

    洛谷P2743传送门 题目大意:给你一个序列,求其中最长的一对相似等长子串 一对合法的相似子串被定义为: 1.任意一个子串长度都大于等于5 2.不能有重叠部分 3.其中一个子串可以在全部+/-某个值后 ...

  5. POJ1743 Musical Theme [后缀数组]

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

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

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

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

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

  8. POJ-1743 Musical Theme(后缀数组)

    题目大意:给一个整数序列,找出最长的连续变化相同的.至少出现两次并且不相重叠一个子序列. 题目分析:二分枚举长度进行判定. 代码如下: # include<iostream> # incl ...

  9. poj1743 Musical Theme 后缀数组的应用(求最长不重叠重复子串)

    题目链接:http://poj.org/problem?id=1743 题目理解起来比较有困难,其实就是求最长有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1 ...

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

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

随机推荐

  1. 多线程wait和notify实现1212

    package threadT; public class ThreadMain { public static void main(String args[]) { final Object obj ...

  2. LN : leetcode 730 Count Different Palindromic Subsequences

    lc 730 Count Different Palindromic Subsequences 730 Count Different Palindromic Subsequences Given a ...

  3. 【学习笔记】Base64编码解码原理及手动实现(C#)

    1.[Base64编码原理]@叶落为重生 -base64的编码都是按字符串长度,以每3个8bit的字符为一组,-然后针对每组,首先获取每个字符的ASCII编码,-然后将ASCII编码转换成8bit的二 ...

  4. Python3基础教程(十八)—— 测试

    编写测试检验应用程序所有不同的功能.每一个测试集中在一个关注点上验证结果是不是期望的.定期执行测试确保应用程序按预期的工作.当测试覆盖很大的时候,通过运行测试你就有自信确保修改点和新增点不会影响应用程 ...

  5. node.js从入门到放弃(二)

    上章讲了学习node,应该去学习什么,对这些框架去进行学习现在咋们聊聊如何用原生来进行操作 主要来讲一下events-事件触发器 events是什么东西呢?他的英文翻译,活动,事件的意思,在计算机语言 ...

  6. luogu P3916 图的遍历

    P3916 图的遍历 题目描述 给出 N 个点, M 条边的有向图,对于每个点 v ,求 A(v) 表示从点 v 出发,能到达的编号最大的点. 输入输出格式 输入格式: 第1 行,2 个整数 N,MN ...

  7. 枚举为何不能设置成public?

    听到测试与开发争论,为何枚举不能用public,用public怎么了?对于这个我也不知道到底能不能用,于是就去查了查资料. 解答: 枚举被设计成是单例模式,即枚举类型会由JVM在加载的时候,实例化枚举 ...

  8. Mysql中max函数取得的值不是最大

    ①问题:遇到一个很有意思的问题,这里记录一下, 就是在使用max函数的时候发现取得的最大值其实不是最大值. 比如: 某一列中有10000000,和9999999, 其最大值应该是10000000但是查 ...

  9. jdk环境变量配置至第一个简单程序运行成功

    桌面右键单击我的电脑,属性,高级,环境变量,然后再系统变量中配置(也可在用户变量中配置) 在配置环境变量时限查看是否已存在变量名称,有则添加路径,没有则创建再添加路径 /* JAVA_HOME% C: ...

  10. 常见的linux命令及其翻译

    常见的linux指令 1.ls ll 查看文件信息 2.cd 切换工作目录 cd 或 cd ~ 切换到/home/用户目录 cd. 切换到当前目录 cd.. 切换到上级目录 cd- 切换入上次所在的目 ...