poj1743 Musical Theme 后缀数组的应用(求最长不重叠重复子串)
2013-08-23 11:19
543 查看
题目链接:http://poj.org/problem?id=1743
题目理解起来比较有困难,其实就是求最长有N(1<=N<=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的主题。
题目理解起来比较有困难,其实就是求最长有N(1<=N<=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的主题。
*“主题”是整个音符序列的一个子串,它需要满足如下条件: *1.长度至少为5个音符 *2.在乐曲中重复出现(可能经过转调,“转调”的意思是主题序列中每个音符都被加上或减去了同一个整数值。) *3.重复出现的同一主题不能有公共部分。 * 所以1,2,3,4,5和6,7,8,9,10是同一个主题 思路: 先转化成相邻两项的差值,然后就是找不可重叠重复子串。 详细解释可以参考:http://hi.baidu.com/ahnkftravhdhkyr/item/346115451d98e8fedc0f6ccd
#include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> usingnamespacestd; #definemaxn20010 intwa[maxn],wb[maxn],wv[maxn],wq[maxn]; intheight[maxn]; ints[maxn]; intrank[maxn]; intsa[maxn]; boolcmp(int*r,inta,intb,intl) {returnr[a]==r[b]&&r[a+l]==r[b+l];} voidda(int*s,int*sa,intn,intm) { inti,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++)wq[i]=0; for(i=0;i<n;i++)wq[x[i]=s[i]]++; for(i=0;i<m;i++)wq[i]+=wq[i-1]; for(i=n-1;i>=0;i--)sa[--wq[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { for(p=0,i=n-j;i<n;i++)y[p++]=i; for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j; for(i=0;i<n;i++)wv[i]=x[y[i]]; for(i=0;i<m;i++)wq[i]=0; for(i=0;i<n;i++)wq[wv[i]]++; for(i=1;i<m;i++)wq[i]+=wq[i-1]; for(i=n-1;i>0;i--)sa[--wq[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } return; } voidgetHeight(int*s,intn) { inti,j,k=0; for(i=1;i<=n;i++)rank[sa[i]]=i; for(i=0;i<n;i++) { if(k)k--; j=sa[rank[i]-1]; while(s[i+k]==s[j+k])k++; height[rank[i]]=k; } } boolcheck(intn,intk) { intMax=sa[1],Min=sa[1]; for(inti=2;i<=n;i++) { if(height[i]<k)Max=Min=sa[i]; else { if(sa[i]<Min)Min=sa[i]; if(sa[i]>Max)Max=sa[i]; if(Max-Min>k)return1; } } return0; } intmain() { intn; while(scanf("%d",&n)!=EOF&&n) { for(inti=0;i<n;i++)scanf("%d",&s[i]); for(inti=0;i<n-1;i++)s[i]=s[i+1]-s[i]+100; n--; s =0; da(s,sa,n+1,200); getHeight(s,n); intans=-1; intlow=4,high=n/2; while(low<=high) { intmid=(low+high)/2; if(check(n,mid)) { ans=mid; low=mid+1; } elsehigh=mid-1; } if(ans<4)cout<<"0"<<endl; elsecout<<ans+1<<endl; } return0; }
相关文章推荐
- 【poj1743-Musical Theme】不可重叠最长重复子串-后缀数组
- POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)
- poj 1743 Musical Theme (后缀数组 不可重叠最长重复子串)
- POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)
- POJ-1743 Musical Theme (后缀数组 不重叠最长重复子串)
- pku 1743 Musical Theme 最长重复不重叠子串 后缀数组
- poj 1743 Musical Theme 【后缀数组 最长不重叠重复子串】
- poj1743 Musical Theme 后缀数组之不可重叠最长公共子串
- POJ - 1743 Musical Theme (后缀数组求不可重叠最长重复子串)
- POJ 1743 Musical Theme 后缀数组 不可重叠最长重复子串
- POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)
- Poj 1743 Musical Theme (后缀数组 不可重叠最长重复子串)
- POJ 1743 Musical Theme (后缀数组加二分求不可重叠最长重复子串)
- POJ 1743 Musical Theme 后缀数组 最长重复不相交子串
- POJ 1743 Musical Theme 后缀数组 不可重叠最长反复子串
- POJ 1743 Musical Theme 【后缀数组】最长不可重叠子串
- POJ 1743 - Musical Theme 最长不重叠重复子串
- 【后缀数组 不重叠重复最长子串】POJ - 1743 Musical Theme
- POJ 1743 Musical Theme (不可重叠最长重复子串)
- Poj 1743——Musical Theme——————【后缀数组,求最长不重叠重复子串长度】