博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ1743 Musical Theme(二分+后缀数组)
阅读量:4698 次
发布时间:2019-06-09

本文共 1763 字,大约阅读时间需要 5 分钟。

题目大概是给n个数组成的串,求是否有多个“相似”且不重叠的子串的长度大于等于5,两个子串相似当且仅当长度相等且每一位的数字差都相等。

 

这题是传说中楼教主男人八题之一,虽然已经是用后缀数组解决不可重叠最长重复子串的经典题了。。但其实没那么简单,题目数据不强,网上一些代码都是不正确的。

  • 首先把问题转化成重复子串的问题:把原串每一位都与前一位相减。这样得出的新串如果有两个长度为n的子串相同,那么它们对应在原串的长度n+1的子串也就相似。
  • 所以接下来要求的就是这个新串不可“重叠”最长重复子串——问题就在这儿,这不只是要求不可重叠,还要求两个子串要隔至少一个位置,因为如果两个子串靠在一起这样反应到原串那两个子串各自的首尾是重合的。

比如数据:9  1 1 1 1 1 1 1 1 1

隔至少一个位置其实只要原本的if(mx-mm>=k)改成if(mx-mm>k)就行了。

 

最后大概描述一下不可重叠最长重复子串的解法:

  • O(logn)二分枚举子串长度,判断解是否成立
  • O(n)判断长度是否成立:把互相之间LCP大于等于长度的分为一组,这通过个扫一遍height即可,因为后缀是有序的,相邻的后缀间的LCP必定的极大的;接下来就找到每个组里后缀sa值最大和最小的,如果差值大于(等于)k就成立,因为这样小下标的后缀沿着LCP下去走k步才不会盖到大下标的后缀。

 

另外,说一下二分枚举解,二分具体写法很多吧,也不知道正不正确。。我那样的写法我发现:

  • 如果是求最小解,mid要取floor,即mid=(left+right)/2
  • 如果是求最大解,mid要取ceil,即mid=(left+right+1)/2

看起来好像是这个样子的。。

1 #include
2 #include
3 #include
4 using namespace std; 5 #define MAXN 22222 6 #define INF (1<<30) 7 int wa[MAXN],wb[MAXN],wv[MAXN],ws[MAXN]; 8 int cmp(int *r,int a,int b,int l){ 9 return r[a]==r[b] && r[a+l]==r[b+l];10 }11 int sa[MAXN],rank[MAXN],height[MAXN];12 void SA(int *r,int n,int m){13 int *x=wa,*y=wb;14 15 for(int i=0; i
=0; --i) sa[--ws[x[i]]]=i;19 20 int p=1;21 for(int j=1; p
=j) y[p++]=sa[i]-j;25 for(int i=0; i
=0; --i) sa[--ws[wv[i]]]=y[i];30 swap(x,y); x[sa[0]]=0; p=1;31 for(int i=1; i
=k){48 mm=min(mm,min(sa[i],sa[i-1]));49 mx=max(mx,max(sa[i],sa[i-1]));50 if(mx-mm>k) return 1;51 }else{52 mx=-INF,mm=INF;53 }54 }55 return 0;56 }57 int main(){58 while(~scanf("%d",&n) && n){59 for(int i=0; i
>1;65 while(l
>1;67 if(isok(mid)) l=mid;68 else r=mid-1;69 }70 if(l>=4) printf("%d\n",l+1);71 else printf("%d\n",0);72 }73 return 0;74 }

 

转载于:https://www.cnblogs.com/WABoss/p/5199261.html

你可能感兴趣的文章
CSS3新增UI样式
查看>>
Python: 自定义类对象序列化为Json串
查看>>
自己胡乱弄得横向blog的CSS,太难看了- - ||||||,所以决定不用了。
查看>>
污染物在线自动监控(监测)系统数据传输标准 (HJ212-2017)-空气质量监测数据包构造...
查看>>
BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT维护最大生成树 主席树
查看>>
springmvc访问静态资源
查看>>
ubuntu 上安装mysql
查看>>
asp.net mvc 3 unobtrusive client side validation not working in IE
查看>>
基于C语言EOF与getchar()的使用详解
查看>>
java 反射和泛型-反射来获取泛型信息
查看>>
Linux 内核PCI去除一个设备
查看>>
Crontab- Linux必学的60个命令
查看>>
rpmbuild - 构建 RPM 打包
查看>>
如何在Windows的PHPstudy中使用redis数据库
查看>>
数字三角形
查看>>
多线程
查看>>
finder怎么才能找到library
查看>>
不生成Excel文件,将Datatable数据 Response.write 输出生成Excel (转载)
查看>>
MOSS版本一览
查看>>
【转】URL和URI的区别
查看>>