POJ 3261 Milk Patterns(后缀数组)
来源:互联网 发布:淘宝买家好评 编辑:程序博客网 时间:2024/06/11 07:06
POJ 3261 Milk Patterns(后缀数组)
http://poj.org/problem?id=3261
题意:
给你一个长N的数字串和K,要你在数字串中找到那个最长的字串,该字串在原始串中至少出现了K次.问这个最长字串的长度.
分析:
罗穗骞论文例题.
这道题是后缀数组的一个简单应用。做法比较简单,只需要求height数组里的最大值即可。
首先求最长重复子串,等价于求两个后缀的最长公共前缀的最大值。因为任意两个后缀的最长公共前缀都是height数组里某一段的最小值,那么这个值一定不大于height数组里的最大值。所以最长重复子串的长度就是height数组里的最大值。这个做法的时间复杂度为O(n)
同样建立后缀数组,求出sa和height.将原始问题边为判定问题:是否存在长度为l的串至少出现了k次.
将height分组,每组内的相邻后缀的公共前缀>=l,则看是否存在一组内的后缀数目>=k.
AC代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=20000+100;const int maxm=1000000+100;struct SuffixArray{ int s[maxn]; int sa[maxn],rank[maxn],height[maxn]; int t1[maxn],t2[maxn],c[maxm],n; void build_sa(int m) { int i,*x=t1,*y=t2; for(i=0;i<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[i]=s[i]]++; for(i=1;i<m;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i; for(int k=1;k<=n;k<<=1) { int p=0; for(i=n-k;i<n;i++) y[p++]=i; for(i=0;i<n;i++)if(sa[i]>=k) y[p++]=sa[i]-k; for(i=0;i<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[y[i]]]++; for(i=1;i<m;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1; x[sa[0]]=0; for(i=1;i<n;i++) x[sa[i]]= y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]? p-1:p++; if(p>=n) break; m=p; } } void build_height() { int i,j,k=0; for(i=0;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; } } bool check(int l,int k)//长l的出现k次以上的串 { int cnt=0; for(int i=1;i<n;i++) { if(height[i]<l)//新的一组开始 cnt=1; else { cnt++; if(cnt>=k) return true; } } return false; }}sa;int main(){ int n,k; while(scanf("%d%d",&n,&k)==2&&n&&k) { for(int i=0;i<n;i++) { scanf("%d",&sa.s[i]); sa.s[i]++; } sa.s[n]=0; sa.n=n+1; sa.build_sa(1000000+2); sa.build_height(); int min=0,max=n; while(min<max) { int mid=min+(max-min+1)/2; if(sa.check(mid,k)) min = mid; else max=mid-1; } printf("%d\n",min); } return 0;}
阅读全文
0 0
- poj 3261 Milk Patterns 【后缀数组】
- POJ 3261 Milk Patterns(后缀数组)
- Milk Patterns(poj 3261,后缀数组)
- poj 3261 Milk Patterns(后缀数组)
- POJ 3261 Milk Patterns(后缀数组)
- poj 3261 Milk Patterns(后缀数组)
- POJ 3261 Milk Patterns(后缀数组)
- 【后缀数组】【poj 3261】Milk Patterns
- 【POJ】3261 Milk Patterns 【后缀数组】
- POJ 3261 Milk Patterns 后缀数组
- poj 3261 Milk Patterns (后缀数组)
- POJ 3261 Milk Patterns (后缀数组)
- POJ 3261 Milk Patterns (后缀数组)
- POJ 3261 Milk Patterns 后缀数组+二分
- poj 3261 Milk Patterns (后缀数组)
- poj 3261 Milk Patterns(后缀数组)
- poj 3261 Milk Patterns 后缀数组 二分
- poj 3261 Milk Patterns(后缀数组)
- ELK实时日志分析平台部署搭建详细实现过程
- Python接口测试之unittest框架(五)
- tp3.1在php5.6+模板不显示或者日志文件很多错误解决办法
- Lucene(一)创建索引
- perl笔记(一)
- POJ 3261 Milk Patterns(后缀数组)
- 软件开发设计模式(一)-单例模式
- window对象
- 【Java】使用Apache POI生成和解析Excel文件
- C语言算法检验 2.9题
- 进程控制(二)进程控制编程
- 微信网页开发异常——签名失败
- uva 232 Crossword Answers
- 关于接口调取和输出