[后缀数组+二分] hdu 4080 Stammering Aliens
2014-08-29 17:17
399 查看
题意:最长重复出现至少k次的可重叠子串且输出最靠右的子串起始位置的下标。
注意
2
ababcece
输出的是
2 6
思路:同样的后缀数组加上二分长度,这里因为要求是要最右边的,所以在二分的时候可以存一下每次取最大的值就好了。
注意
2
ababcece
输出的是
2 6
思路:同样的后缀数组加上二分长度,这里因为要求是要最右边的,所以在二分的时候可以存一下每次取最大的值就好了。
#include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #include"algorithm" #include"iostream" #include"map" using namespace std; #define N 40350 int wa ,wb ,wv ,wws ; int sa ,ra ,height ; int v ; char fuck ; int cmp(int *r,int a,int b,int l) { return r[a]==r[b]&&r[a+l]==r[b+l]; } void da(int n,int m) { int i,j,p,*x=wa,*y=wb; for(i=0; i<m; i++) wws[i]=0; for(i=0; i<n; i++) wws[x[i]=v[i]]++; for(i=1; i<m; i++) wws[i]+=wws[i-1]; for(i=n-1; i>=0; i--) sa[--wws[x[i]]]=i; for(j=1,p=1; p<n; j*=2,m=p) { for(i=n-j,p=0; 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++) wws[i]=0; for(i=0; i<n; i++) wws[wv[i]]++; for(i=1; i<m; i++) wws[i]+=wws[i-1]; for(i=n-1; i>=0; i--) sa[--wws[wv[i]]]=y[i]; for(swap(x,y),p=1,i=1,x[sa[0]]=0; i<n; i++) x[sa[i]]=cmp(y,sa[i],sa[i-1],j)?p-1:p++; } return ; } void gethei(int n) { int i,j,k=0; for(i=1; i<=n; i++) ra[sa[i]]=i; for(i=0; i<n; i++) { if(k) k--; j=sa[ra[i]-1]; while(v[i+k]==v[j+k]) k++; height[ra[i]]=k; } return ; } int ok(int x,int k,int n) { int i; int sum=1,ans=-1; int MAX=-1; for(i=1; i<=n; i++) { if(height[i]>=x) { MAX=max(max(sa[i],sa[i-1]),MAX); //每段中找到最大 sum++; if(sum>=k) ans=max(MAX,ans); //当满足k次的时候 更新ans保证最大 } else { MAX=-1; sum=1; } } return ans; } int main() { int n; while(scanf("%d",&n),n) { scanf("%s",fuck); if(n==1) { printf("%d %d\n",strlen(fuck),0); continue; } int i; int len=strlen(fuck); for(i=0; fuck[i]; i++) v[i]=fuck[i]-'a'+2; v[len]=0; da(len+1,30); gethei(len); int l=1,r=len; int MAX=-1,ans=-1; while(l<=r) { int mid=(l+r)/2; int tep=ok(mid,n,len); if(tep!=-1) { MAX=tep; ans=mid; l=mid+1; } else r=mid-1; } if(ans==-1) puts("none"); else printf("%d %d\n",ans,MAX); } return 0; }
相关文章推荐
- [HDU 4080] Stammering Aliens (字符串哈希+二分)
- hdu 4080 Stammering Aliens 二分 hash
- hdu 4080 Stammering Aliens 二分 hash
- HDU 5558 后缀数组+二分
- HDU 4080 Stammering Aliens (后缀数组 + 二分答案)
- HDU 4080 Stammering Aliens(后缀数组+二分)
- hdu 1507 Uncle Tom's Inherited Land* (二分匹配)
- hdu 5248(二分)
- 【HDU】5046 Airport 二分+重复覆盖
- poj 1019 Number Sequence && hdu 1597 find the nth digit(二分,模拟)
- hdu The Frog's Games(二分枚举)
- HDU 1598 find the most comfortable road 二分+bfs or 并查集枚举
- HDU 4791 Alice's Print Service【二分查找】
- hdu5432 二分
- hdu 5515 Game of Flying Circus(二分、模拟)
- HDU 2063过山车(二分最大匹配之最大匹配)
- 【HDU】5248-序列变换(贪心+二分)
- HDU 1054 Strategic Game 二分匹配 | 树型DP | 贪心
- HDU 3715 Go Deeper【2-SAT+二分】
- HDU 5289 Assignment (二分+RMQ)