POJ 3261 Milk Patterns

原创 2012年03月24日 08:56:43

http://poj.org/problem?id=3261

题意:N头牛,每头牛有一个编号,求可重叠的至少出现K次的最大子串。

思路: 后缀数组+二分 。 二分答案,然后将后缀分成若干组。不同的是,这里要判断的是有没有一个组的后缀个数不小于k。如果有,那么存在k 个相同的子串满足条件,否则不存在。这个做法的时间复杂度为O(nlogn)。

代码: 

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define MAXN 20010
#define MAXN1 1000010
int num[MAXN] ;
int sa[MAXN] , rank[MAXN] ,height[MAXN] ;  
int wa[MAXN1] , wb[MAXN1] ,wv[MAXN1],wd[MAXN1] ;   
int N,M;  
int cmp(int *r , int a , int b , int l){  
    return r[a] == r[b] && r[a+l] == r[b+l] ;     
}  

void DA(int *r,int n,int m){        //O(NlogN)  
    int i, j , p , *x=wa, *y=wb,*t ;  
    for( i = 0 ; i < m ; i++ )   wd[i] = 0 ;  
    for( i = 0 ; i < n ; i++ )       wd[x[i]=r[i]] ++ ;  
    for( i = 1 ; i < m ; i++ )       wd[i] += wd[i-1] ;  
    for( i = n-1 ;i >= 0 ; i-- )     sa[--wd[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++)    wd[i] = 0 ;  
        for( i = 0 ; i < n ; i++)    wd[wv[i]] ++ ;  
        for( i = 1 ; i < m ; i++)    wd[i] += wd[i-1] ;  
        for( i = n-1 ; i >= 0 ; i--) sa[ --wd[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++;   
        }     
    }  
}   
  
void calHeight(int *r , int n){  
    int i , j , k = 0 ;  
    for( i = 1 ; i <= n ; i++)   rank[sa[i]] = i ;  
    for( i = 0 ; i < n ; height[ rank[i++]]=k){  
        for( k ? k-- : 0 , j=sa[rank[i]-1]; r[i+k]==r[j+k] ; k++) ;   
    }     
}
bool is_ok(int len){
	int i = 1 ;
	while(i <= N){
		while(i <= N && height[i]<len)	i++ ;
		int c = 1 ;
		while(i <= N && height[i]>=len){		//以height[]数组分组
			i++ ;
			c ++ ;	
		}
		if(c >= M)	return true ;
	}	
	return false ;
}

int main(){
	while(scanf("%d %d",&N,&M) == 2){
		for(int i=0;i<N;i++){
			scanf("%d",&num[i]);	
			num[i]++ ;
		}		
		num[N] = 0 ;
		DA(num,N+1,MAXN1);
		calHeight(num, N) ;
		int low, high , mid ;
		low = 1 ; high = N ;
		while(low < high){
			mid = (low + high + 1) >> 1;
			if(is_ok(mid))	
				low = mid ;
			else 
				high = mid - 1;
		}
		printf("%d\n",low);
	}
	return 0 ;	
}


POJ 3261 Milk Patterns(SA 求最长可重叠重复K次子串)

题目链接:Click here~~ 题意: 给一个字符串(int 型),求至少出现 K 次的最长子串,这 K 个子串可以重叠。 解题思路: 如果明白了上一题,这一题就很好想了。 分组后,一...
  • dgq8211
  • dgq8211
  • 2013年08月07日 08:57
  • 1086

poj3261之可重叠的k次最长重复子串

Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 8511   ...
  • xingyeyongheng
  • xingyeyongheng
  • 2013年11月18日 22:26
  • 2649

(Relax 后缀数组1.2)POJ 3261 Milk Patterns(求一个长度为n的整数序列中,至少出现k次的子序列的最长的长度)

【题意】 给定一个长度为n的整数序列,求其中至少出现k次的子序列长度最长为多长 【输入】 第一行n和k 接下来n个数字描述序列 【输出】 一个数字,表示至少出现过k次的子序列最长长度 ...
  • caihongshijie6
  • caihongshijie6
  • 2013年11月25日 10:04
  • 1398

POJ 3261 Milk Patterns(后缀数组 + 可重叠最长重复子串次数大于k)

Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14392   ...
  • just_sort
  • just_sort
  • 2016年10月16日 15:41
  • 168

POJ 3261 Milk Patterns (离散化+后缀数组 可重叠k次最长重复子串)

题意:给出一串长度为n的字符,再给出一个k值,要你求重复次数大于等于k次的最长子串长度 思路:首先离散化,然后采用后缀数组的常用处理方法,二份答案,按照二份值k将height数组分组,对于k是否可行...
  • whyorwhnt
  • whyorwhnt
  • 2013年08月05日 20:25
  • 735

[后缀数组+离散化+二分] poj 3261 Milk Patterns

题意:求至少重复k次的可重叠子串
  • wdcjdtc
  • wdcjdtc
  • 2014年08月29日 16:58
  • 517

POJ 3261 Milk Patterns 最长出现k次的子串长度(后缀数组)

Milk PatternsTime Limit: 5000MS Memory Limit: 65536K DescriptionFarmer John has noticed that t...
  • w4149
  • w4149
  • 2017年07月27日 19:36
  • 96

POJ 3261 Milk Patterns(后缀数组+二分)

Description 给出一个字符串,求至少出现k次的可重叠的最长子串的长度 Input 第一行为两个整数n和k(1...
  • V5ZSQ
  • V5ZSQ
  • 2016年05月03日 14:27
  • 296

【后缀数组 重叠重复字串个数大于k的最长长度】POJ - 3261 Milk Patterns

Problem Description 给你一个长度为n的数组(串),数组的数值范围1-1e6。让你求可重叠重复字串个数大于k的最长长度是多少 可重叠最长重复字串: 例如abcdbcd...
  • bbbbswbq
  • bbbbswbq
  • 2017年12月12日 17:06
  • 24

POJ 3261 Milk Patterns(后缀数组 重复出现K次字串的长度)

Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7956   ...
  • sunrainchy
  • sunrainchy
  • 2013年07月29日 19:02
  • 495
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 3261 Milk Patterns
举报原因:
原因补充:

(最多只允许输入30个字)