资源限制
时间限制: 100ms内存限制: 256.0MB
问题的说明
当给定长度为n的数列,求出至少出现k次的最长重复部分列的长度时,该k个部分列可以重叠。 保证子串至少出现k次。
输入格式
第一行:两个整数n,k;
第2行: 2到n 1行: n个整数。 这n个整数构成一个数列。
输出格式
表示最长重复子列长度的整数。
样品输入
8 2
1 2 3 2 3 2 3 1
样品输出
4
数据规模和承诺
0n20000,2kn,0数列中的整数 1000000
后缀数组:suff[i]表示以第一位开始的后缀。 后缀数组sa[i]:指示对所有后缀进行排序后,后缀在原始字符串中排名为I的位置。 顺序数组rank[i]:对所有后缀进行排序后,显示原始字符串中的第I个当前顺序。
三者关系:
求后缀数组:构建sa数组的方法一般有两种。
倍频算法: o(nlogn ) DC3算法: o ) n )算法中为基数排序
倍增算法和基数排序可以自己在网上调查了解。
LCP-最长公共前缀: http://www.Sina.com/:suff[sa[I]]和suff[sa[I1]]的最大公共前缀,即排名后两个相邻后缀的最长公共前缀
height[i]
后缀数组的应用: 1、给可重复的最长重复子串赋予字符串,求最长重复子串。 这两个子列可以重复
2、对不能重复的最长重复部分串给出一个字符串,求最长重复部分串,这两个部分串不能重复
3、对重叠的k次最长重复子串给出字符串,求出至少出现k次的最长重复子串,这k个子串重叠
能力有限,可以自己理解:处理后缀数组——字符串的强大工具
本题源程序: # includeiostreamusingnamespacestd; # define maxsize 100000 intrank [ maxsize ],sa[maxsize]; int height[maxsize]; int sec[maxsize],t[maxsize]; int s[maxsize]; //接受用户输入的数组int num=maxsize; int len,number; //长度和次数inline void SA ()//sa )数组) for(intI=1; i=num; I ) t(I )=0; for(intI=1; i=len; I ) t[Rank[i]=s[i]]; for(intI=1; i=num; I ) t(I )=t(I-1 ); for(intI=len; i=1; I----sa[t[rank[I]]----]=I; for(intk=1; k=len; k({intCNT=0; for(intI=len-k1; i=len; I ) sec[ cnt]=i; for(intI=1; i=len; I ) if(sa[I]k ) sec[ cnt]=sa[i] - k; for(intI=1; i=num; I ) t(I )=0; for(intI=1; i=len; I ) t[Rank[i]]; for(intI=1; i=num; I ) t(I )=t(I-1 ); for(intI=len; i=1; I---- sa [ t [ rank [ sec [ I ]-- ]=sec [ I ],sec[i]=0; WAP(rank,sec ); Rank[sa[1]]=1,cnt=1; for(intI=2; i=len; I ) rank [ sa [ I ]=(sec [ sa [ I ]==sec [ I-1 ] ) sec[sa[I]k]==sec[sa[I-1]k]? cnt : cnt; if(CNT==len ) break; num=cnt; }}void Getheight ()//height )数组({int j,k=0; for(intI=1; i=len; I ) if(k ) k----; int j=sa[Rank[i] - 1]; while(s[Ik]==s[jk] ) k; height[Rank[i]]=k; }boolcheck(intmid )/height )数组进行分类,计数组内是否满足重复次数。 {int group=0; for(intI=1; i=len; I ) if(Height[I]=mid ) group; if(group=number )返回真; if(Height[I]mid ) group=1; }return false; }int main () {cin len number; for(intI=1; i=len; I ) cin s[i]; SA (; Getheight (; int front=1,rear=len; 输入最大值=0; wile(front=rear )//二分法! {intmid=(frontrear )/2; if(check(mid ) ) {front=mid 1; maxlen=mid; }elserear=mid - 1; }cout maxlen endl; }评价结果: